从文件中扫描C

问题描述:

我试图使用下面的代码扫描文件中的字符串。但我的程序打印怪异的字符。任何想法如何阻止这种情况,以及如何在打印字符串时在单词之间保留空格?从文件中扫描C

这里是文件(test.txt的)的内容  (test.txt)

这里是我的程序的输出:

output

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct 
{ 
    char word[80]; 
    int length; 
    int freq; 
} sent; 

int main() 
{ 
    sent a[50]; 
    int v,status; 
    int i=0,cnt=0; 
    char*y; 

    FILE*p; 
    p=fopen("C:\\Users\\User\\Desktop\\test.txt","r"); 
    status=fscanf(p,"%s",a[i].word); 
    while(status !=EOF){ 
     i++; 
     status=fscanf(p,"%s",a[i].word); 
    } 
    for(i=0;i<50;i++) 
    { 
     char *y=strtok(a[i].word,"[email protected]#$%&*?."); 

     while(y!=NULL) 
     { 
     printf("%s",y); 
     y=strtok(NULL,"[email protected]#$%&*?."); 

     } 
    } 
} 
+6

请张贴test.txt的内容。我的猜测是你文件中没有50个单词。 –

+0

fscanf(p,“%s”,a [i] .word);可以以缓冲区溢出结束,使用fscanf(p,“%79s”,a [i] .word);或fgets()。并在fopen() – 12431234123412341234123

这只是字符串操作。我调试并修改了一下程序,以便有文本输出而不是垃圾。您可能需要再修改一下,但它现在会打印文件的内容。你得到垃圾字符的原因是,当字符串没有被终止时,循环不知道何时停止,所以你从其他东西获得内存内容。推荐的方法是fgets来读取文件并保留空白。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct { 
    char *word; 
    int length; 
    int freq; 
} sent; 

int words(const char *sentence) { 
    int count, i, len; 
    char lastC; 
    len = strlen(sentence); 
    if (len > 0) { 
     lastC = sentence[0]; 
    } 
    for (i = 0; i <= len; i++) { 
     if (sentence[i] == ' ' && lastC != ' ') { 
      count++; 
     } 
     lastC = sentence[i]; 
    } 
    if (count > 0 && sentence[i] != ' ') { 
     count++; 
    } 
    return count; 
} 

int main() { 
    sent a[50]; 
    int v, status; 
    int i = 0, cnt = 0; 
    FILE *p; 
    p = fopen("data.txt", "r"); 
    char buf[100], title[100]; 
    fgets(buf, sizeof buf, p); 
    int j = words(buf); 
    char *yy; 
    yy = strtok(buf, "[email protected]#$&*?%."); 

    while (yy != NULL) { 
     a[i].word = yy; 
     yy = strtok(NULL, "[email protected]#$&*?%."); 
     i++; 
    } 

    for (int k = 0; k<i; k++) { 
     printf("%s", a[k].word); 
    } 
} 

该程序标记缓冲区并保留空白。我将你读取文件的方式改为fgets

的data.txt

其规模从一到十$什么是你最喜欢的字母

输出

的颜色从一个到规模十你最喜欢什么颜色的字母表

+2

之后检查错误请描述您对OP的代码所做的修改,以便它适用于您。 –

+0

@RSahu我加入了改进的代码和更多描述。我希望你再次批准或评论。 –

+0

@ Programmer400 - 你没有提到为什么你的代码更好,或为什么他的代码失败...... – Soren

由于人们评论说,你很可能没有你读文件中的50个字,但你的循环超过50试图环......反正,所以这行

for(i=0;i<50;i++) 

应该进行修改,以

int w; 
for(w=0;w<i;w++) 

并且您应该在循环内替换使用iw(或者您打算在while循环内使用变量cnt,因为该代码中当前未使用该变量)。

而且您需要保护缓冲区溢出,如果您的文件包含超过50个词的话会发生,但这超出了本答案的范围。

更新回答您的评论:

对有字与字之间的空间,你只是简单地将它们添加到输出,就像

printf("%s ",y); 

你的scanf但是将终止字符串扫描任何空格,所以空格(十六进制20),换行符(\ n),制表符(\ t)或返回符号(\ r)将全部为您的字符串的终止字符 - 如果您想保留并输出相同的内容,对于那些人也如

char theString[50]; 
    char theSpace; 
    int matched = scanf("%s%c",theString, theSpace); 

,如果匹配== 2,那么你已经扫描这两个字符串和终止扫描的空间,并且可以打印它像

printf("%s%c",theModifiedString,theSpace); 
+0

所以'我'在这里是指单词的数量,而不是文件中字符的数量.....我计算了文件中的单词,并根据数字更改了循环...它的工作,但没有空格之间的话我怎么能保持他们之间的空间?? ....谢谢你的答案它帮助 –

+0

查看更新的答案 – Soren

+0

如果我使用'printf(“%s”,y);'它不会工作,因为我在这个单词本身的字符之间有特殊字符,所以这个单词中的字符之间会有空格。 –