C - 将值返回到main

时间:2013-04-01 11:35:15

标签: c function return-value

没有找到回答我问题的任何内容,所以请点击:

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

    // ...
}
编辑:好的,我已经成功了,因为有些人基本上都有适合我的解决方案,所以我想在此感谢!不知道我是否可以选择多个答案为正确。

6 个答案:

答案 0 :(得分:2)

您似乎有两个名为error的变量,一个位于add(),另一个位于main(),它们是不同的变量! 你至少需要改变

add(line);

error = add(line);
if (error != 0)
    break;

答案 1 :(得分: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 ...

答案 2 :(得分: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 */
}

答案 3 :(得分:1)

回答评论。新评论变得有点长。

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

fgets没问题。但是,fgets一旦到达换行符就退出读取32位字节。

会在数据末尾添加换行符。

如果它位于文件中当前位置的范围内,那么最后只有\n。它每次执行的操作都会在读取数据的长度内附加一个null,如0x00中的最后一个字节。 AKA C-string终止。

那是:

 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
@

如果\n中没有!line,那么您的代码(while循环)会发生什么? 它不断超越line所在的记忆区域。它要么导致a 段错或它找到两个中止之一 - 如果说:

给你误报
  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


这样也会将line重命名为buf之类,因为代码中可能会混淆(或许)。

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

一个名为is_ok(var)的函数,逻辑上返回1表示true,0表示false表示 但是函数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 写自己很容易。另请阅读this

答案 4 :(得分:0)

我认为你没有使用add()函数返回的值,你就是在正确的方向。

您必须将该功能分配给error = add(line);之类的错误 然后你可以检查那是1所以你返回。
希望这有助于检查必须在每次值变化时进行检查,因此您可能会丢失值1。在while内部使用error = add(line);,变量错误在每个循环中都会获得新值。

答案 5 :(得分:0)

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

main中的此错误变量与add

中定义的错误变量不同
int check = 0;
int error = 0;

当你在main中调用error时,调用main的本地变量,它仍然没有改变。 error中对add的更改是该函数的本地更改。该变量的变化不会反映在main中的error中。

您需要int error = add(line);之类的内容 主要的if(error)