2013-11-23 66 views
1

所以我现在有问题与我的程序。我试图让它打开一个文件计数行倒回,然后通过文件来存储变量。 String String String int是文件的格式,但我在计算行数后遇到了问题。我可以将数字打印到屏幕上,但在打印后立即出现分段错误。我不知道为什么文件输入int字符串c

int countLines(FILE * fin){ 
int count=0; 
char street[100]; 
char city[100]; 
char state[3]; 
int zip; 

do{ 
    fgets(street, 100, fin); 
    fgets(city, 100, fin); 
    fgets(state, 3, fin); 
    fscanf(fin, "%d\n", &zip); 
    count++; 
}while(!feof(fin)); 

rewind(fin); 

return count; 

}

lines=countLines(fin);是我如何调用该函数。我究竟做错了什么?

+0

fgets读取整行直到文件或换行符结束。你的“String String String int”值是一行一行还是一行一行? – tyilmaz

+0

这是每个条目的一行。 字符串\ n 字符串\ n 字符串\ n int \ n – kevorski

+0

对于结果代码,不应检查任何*这些fgets()调用,也不要检查fscanf()是否应放在列表顶部“what-i'm-doing-wrong”,之后不久,通过在while循环中使用'feof()'作为中断条件,[这几乎总是错误的。](http://stackoverflow.com/问题/ 5431941/while-feof-file-is-always-wrong) – WhozCraig

回答

2

不要混合fgets()fscanf()直到你非常舒适与这些功能。他们在一起打球不好。在格式\n是一种白色的空间和将匹配任何数量的连续白色空间,包括多个\n,空格,制表符,等等

// fscanf(fin, "%d\n", &zip); 

推介避免feof()并使用来自fgets()的返回值。

feof()直到尝试读取文件并且未能提供char才会成为真。这不同于“当没有人离开时是真的”。例如:您读取文件的最后一个charfeof()仍然是错误的。代码尝试读取更多(并失败)。 现在feof()是正确的。 (并保持真实)。

是否以简单的方式计算线条并使用对称性。进一步考虑更多错误检查。将邮政编码行读取为一个字符串,然后然后将其解析为一个整数。

int countLines(FILE * fin){ 
    int count=0; 
    char street[100]; 
    char city[100]; 
    char state[100]; 
    char zips[100]; 
    unsigned zip; 

    while (fgets(street, sizeof street, fin) != NULL) { 
    count++; 
    } 
    rewind(fin); 

    if (count%4 != 0) Handle_LineCountNotMultipleof4(); 

    // You could return here, but let's read the file again and get the data. 
    // This is likely part of OP's next step. 
    for (int i=0; i<count; i += 4) { 
    if ((NULL == fgets(street, sizeof street, fin)) || 
     (NULL == fgets(city, sizeof city, fin)) || 
     (NULL == fgets(state, sizeof state, fin)) || 
     (NULL == fgets(zips, sizeof zips, fin)) || 
     (1 != sscanf(zips, "%u", &zip))) handle_error(); 
    // Remember street, city, state, still have an ending \n 
    do_something(street, city, state, zip); 
    } 
    return count; 
} 

或者,要计算行数,请使用以下内容。如果排队很长,在阅读中会出现奇怪的困难,所以让我们一起检查一下。如果你喜欢简单的答案,拿出这个东西line length东西。您可以使用Maxline+1作为缓冲区大小而不是固定的100.

size_t Maxline = 0; 
    size_t Curline = 0; 
    int ch; 
    while ((ch = fgetc(fin)) != EOF) { 
    Curline++; 
    if (ch == '\n') { 
     count++; 
     if (Curline > Maxline) MaxLine = Curline; 
     Curline = 0; 
    } 
    } 
    if ((Maxline + 1) > 100) TroubleAhead() ; // Trouble with future (fgets(buf, 100, fin), use bigger buffers 
    rewind(fin); 
+0

当我试图让存储到变量(街道,城市,州,邮编),我得到了countLines的函数调用后分段错误的值。这是什么原因?这是我将数字打印到屏幕后。是因为后面的\ n?你如何从int删除尾部\ n? – kevorski

+0

@kevorski为了调试,让'do_something()'为'printf('s:<%s> c:<%s> S:<%s> z:<%u> \ n“,street,city,state,zip)''。仔细检查你的和我的'zips'(一个字符数组)和'zip'(一个整数)的用法。 – chux

+0

我得到了它的工作。现在只要有其他问题现在哈哈 – kevorski

0

fgets试图阅读整行,而不是一个字,这似乎是你所希望的。 因此,你传递给它的缓冲区不够大,他们不会得到你想要的东西,而且你每增加一行3次就会增加一次计数,而fscan通常不会读取一行,从而使该行的剩余部分干扰随着你的下一次阅读。

如果您想阅读单词,请使用%s试试scanf。如果你想阅读固定数量的字符,请尝试fread。

+0

我知道我每4行增加一次。我使用的街道城市状态zip是一个结构。你能举出scanf的例子吗?现在,我只是得到了一个空白页面,一旦我输入文件名@RichardPlunkett – kevorski