2

没有找到任何回答我的问题的东西,所以这里是:

我想将一个整数从一个函数返回到我的 main 以供进一步使用,特别是它是一个add()从文本文件中的条目创建列表的函数。我要返回的整数称为错误,在函数开头声明为0 ,并在满足条件时更改为1(在我的情况下,如果找到除 az、AZ、- 和 ' ' 以外的任何字符) . 如果满足此条件,我想将错误(作为1)返回给主函数,否则我将其返回为0。然后,在我的 main 中,我有一个 if 语句来检查错误是否为1然后打印一条错误消息并返回 1。这可能吗?我已经尝试了一些东西,但它不起作用,如果我在我的 main 中将错误变量初始化为 0,那么 add 函数不应该在我的错误情况下将其更改为 1 吗?我不想使用全局变量,只想将 add 函数实现到 main 作为最后的手段。

抱歉,如果这完全是胡说八道,我非常初学者。

int add(char line[])
{
    struct node *newnode = (struct node *) malloc(sizeof(struct node));
    struct node *walker = newnode;

    strcpy(newnode->name, line);                

    int check = 0;
    int error = 0;

    while(line[check] != '\n')
    {
        if(line[check] == '!')
        {
            error = 1;
            return error;       
        }
        check++;
    }
    .    //Here is just the creation of the list elements
    .    //If the functions reaches end, it returns error with 0 as value
    .
    }

主要的:

int main()
{
    FILE *fp;
    char line[33];
    int error = 0;

    fp = fopen("test.txt", "r");

    if(!fp)
    {
        printf("Error.");
        return 0;
    }

    while(fgets(line, 33, fp) != NULL)
    {
        add(line);
    }
    fclose(fp);

    if(error == 1)
    {
        printf("error");
        return 1;
    }

    // ...
}

编辑:好的,我已经成功了,因为有几个人基本上对我有正确的解决方案,我想在这里说声谢谢!不知道我是否可以选择多个答案作为正确答案。

4

6 回答 6

2

您似乎有两个变量error,一个 inadd()和另一个 in main(),它们是不同的变量!你至少需要改变

add(line);

error = add(line);
if (error != 0)
    break;
于 2013-04-01T11:43:56.960 回答
1

在函数 add() 中,更改行

if(line[check] == '!')

if(!ok(line[check]))

并编写函数 ok 以便它检查提供的参数是否不是英文字母或空格。现在您只需检查您的行是否包含!。也许这是一个错误。

你可以这样写:

int ok(char ch){
    return (ch>='A' && ch<='Z') || (ch>='a' && ch<='z') || ch==' ';
}

总的来说,你应该有这样的东西:

while(fgets(line, 33, fp) != NULL)
{
    error=add(line);
    if(error==1)  ... handle error ...
于 2013-04-01T11:43:50.910 回答
1

您拥有的变量add()main()局部变量。这意味着它们包含的值不能在各自的函数之外使用。所以当add()返回一个值时,你需要有一个变量main()来收集它。所以,

while(fgets(line, 33, fp) != NULL)
{
      /* Here when the add returns 1 or 0, the value is collected 
       * by the "error" variable of main function */
      error = add(line);
      if( error == 1 ) break ; /* Its Simple :-) */
      /* Once add() returns, you will break from the while loop
         will continue with the main() instructions ahead */
}
于 2013-04-01T11:52:42.670 回答
1

对评论的侧面回答。新评论变得有点长。

(这是关于while(line[check]) != '\n') {

fgets没关系。但是fgets一旦到达换行符读取了 32 个字节,就退出读取。

它不会数据末尾附加换行符。

仅当它\n位于文件中当前位置的范围内时,最后才会出现。它每次做的是附加一个空值,0x00如最后一个字节 - 在读取数据的长度内。又名 C 字符串终止。

那是:

 buf[4];
 line 'a\n'    => buf = {'a', '\n', 0x00}
 line 'ab\n'   => buf = {'a', 'b' , '\n', 0x00}
 line 'abc\n'  => buf = {'a', 'b' , 'c' , 0x00}

换一种方式。buf 中的换行符不是fgets附加内容,而是读取数据的一部分,它也会触发读取停止。因此你有:

fgets 停止阅读,如果:

     IF lenght - 1 bytes read
  OR IF read \n
  OR IF end of file

还; 如果一行超过 32 个字节,则下一次读取将继续从中断处继续,而不是在下一行。

这给出了:

数据:

abc
defghijklmno
pq
rstuv

示例代码:

#include <stdio.h>

int main(int argc, char *argv[])
{

    FILE *fp;
    char *fn = "sample.txt";
    char buf[4];
    int i = 0;

    if (argc > 1)
        fn = argv[1];

    if ((fp = fopen(fn, "r")) == NULL) {
        fprintf(stderr, "Unable to open '%s` for reading.\n", fn);
        return 1;
    }

    while(fgets(buf, 4, fp) != NULL) {
        fprintf(stdout, "%2d: @%s@\n", i++, buf);
    }

    fclose(fp);

    return 0;
}

结果:

 0: @abc@
 1: @
@
 2: @def@
 3: @ghi@
 4: @jkl@
 5: @mno@
 6: @
@
 7: @pq
@
 8: @rst@
 9: @uv
@

在您的代码中,while 循环中发生的情况是,如果没有\n!在其中,line 它会不断超出line驻留的内存区域。它要么导致段错误,要么找到两者之一并中止 - 如果说:

  char line[4]; read 'abcd'

  MEMORY ADDRESS   REF        VALUE
  0xf00            line[0]    a
  0xf01            line[1]    b
  0xf02            line[2]    c
  0xf03            line[3]    0x00
  0xf04            <unknown>  z
  0xf05            <unknown>  x
  0xf06            <unknown>  0x08
  0xf07            <unknown>  A
  0xf08            <unknown>  f
  0xf09            <unknown>  0xfd
  0xf0a            <unknown>  !
  0xf0b            <unknown>  g

这样,您的函数将返回错误,因为它一直读取直到0xf0a 找到的地址!- 但这不是line.


通过这也重命名linebuf或类似的,因为它在代码中令人困惑(也许)。

并且,仅作为建议,考虑返回0成功和!= 0错误,因为这是许多相同格式的函数的惯例。

一个名为 的函数is_ok(var)返回 1 表示真,返回 0 表示假是合乎逻辑的,但一个函数在错误add(var)时返回更合乎逻辑!= 0——就像在错误代码中一样。


编辑评论:

是的。一种正常的方式可能是这样的:

int i = 0;

while (buf[i] && buf[i] != '\n') {
    if (!isalpha(buf[i++]))
        return 1;
}

或者更清楚,但恕我直言,好像一个被标准化为 C一样不需要它,它可以直观地读成这样:

while (buf[i] != 0x00 && buf[i] != '\n') {
    ...

isalpha()是 的一部分ctype.h,但如果你知道它总是 ASCII,那么你自己写就很容易了。也许也读这个。

于 2013-04-01T13:16:17.080 回答
0

我认为您在不使用 add() 函数返回的值的情况下处于正确的方向。

您必须将该函数分配给错误error = add(line); ,然后您可以检查是否是1这样您返回。
希望这当然会有所帮助,因为每次值更改时都必须在其中进行检查,因此您可能会丢失值1。在error = add(line);while 内部,变量 error 在每个循环中都取新值。

于 2013-04-01T11:41:03.057 回答
0
int main()
{
FILE *fp;
char line[33];
int error = 0;

main 中的这个错误变量与在 main 中定义的不同add

int check = 0;
int error = 0;

当您在 main 中调用 error 时,将调用 main 的本地变量,该变量仍然保持不变。error对in的更改add是该函数的局部变量。该变量的变化不会反映在errormain.js 中。

int error = add(line); if(error)你必须在主要的东西

于 2013-04-01T11:46:42.637 回答