为什么这个字符串是空的?

时间:2013-07-11 20:05:16

标签: c string function

我有这个小问题,无法解决 问题是我试图通过要求用户插入函数来加载函数LOAD中的所有四个字符串。一切似乎都很好,我没有得到任何编译器错误。但eaf仍然为空。我尝试了很多方法,甚至用scanfgetsgets_s取代fgets,但没有任何变化。

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

void LOAD(char eaf[], char initials[], char finals[], char symbols[]);
int COMPARE(char s[], char eaf[]);

int main()
{
    char eaf[10],initials[1],finals[10],symbols[5];
    LOAD(eaf, initials, finals, symbols);
    return 0;
}


void LOAD(char eaf[], char initials[], char finals[], char symbols[])
{
    printf("Insert states of the optimized AFD\n");
    scanf( " %s", eaf);

    printf("Insert AFD initial state\n");
    do
    {
        scanf( " %s", initials);
    } while (COMPARE(initials, eaf));

    printf("Insert final state(s)\n");
    do
    {
        scanf( " %s",finals);
    } while (COMPARE(finals, eaf));

    printf("Insert the language symbols\n");
    scanf( " %s",symbols);
}

int COMPARE(char s[], char eaf[])
{
    int i;
    char *ptr;
    for(i; i < strlen(s); i++){
            printf("%d\n", i);
        while(ptr==NULL){
            ptr = strchr(eaf, *s);
        }
    }
    if (ptr == NULL) return 1;
    else return 0;
}

我做错了什么?这只是一个更大的程序的一小部分,但其余部分是无用的,因为eaf是空的。我认为问题是使用scanf,但正如我所说,其他功能也没有用。我希望有人能帮助我。感谢

编辑:我按strlen(eaf)

进行了检查

2 个答案:

答案 0 :(得分:1)

使用“scanf”输入是危险的,你已经走到了那个危险之中。当你要求它以字符串形式读取首字母时,你允许它覆盖“eaf”的内容,并添加终止0。

最终,字符串为空,因为您的数组维度错误。你给“首字母”一个数组大小为1,它没有为尾随的'\ 0'C字符串终止符提供空间。

ideone上查看此代码的实时演示:

#include <stdio.h>

void report(char* eaf, char* initials, char* foo)
{
    printf("eaf = %p, initials = %p, foo = %p\n", eaf, initials, foo);;
    printf("*eaf = %d, *initials = %d, *foo = %d\n", eaf[0], initials[0], foo[0]);
}

void load(char eaf[], char initials[], char foo[])
{
    printf("load\n");
    report(eaf, initials, foo);

    printf("Enter EAF\n");
    scanf(" %s", eaf);
    report(eaf, initials, foo);

    printf("Enter initial state\n");
    scanf(" %s", initials);
    report(eaf, initials, foo);
}

int main(int argc, const char* argv[])
{
    char eaf[10], initials[1], foo[10];
    report(eaf, initials, foo);
    load(eaf, initials, foo);
    report(eaf, initials, foo);

    return 0;
}

你应该在调试器中走过这一步,并观察“eaf”和“姓名缩写”的值,看看你进步时发生了什么。

你必须用C编写这个程序吗?似乎使用诸如perl或python之类的脚本语言对您来说可能更容易。

这是一个开始解决问题的工作C方法,请注意我实际上没有解决问题,但它会让它更容易看到它。

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

void report(char* eaf, char* initials, char* foo)
{
    printf("eaf = %p, initials = %p, foo = %p\n", eaf, initials, foo);;
    printf("*eaf = %d, *initials = %d, *foo = %d\n", eaf[0], initials[0], foo[0]);
}

void load(const char* label, const char* into, size_t intoSize)
{
    assert(intoSize > 1); // can't store a string in 1 character.
    printf("%s\n", label);

    char input[1024] = "";
    fgets(input, sizeof(input), stdin);

    size_t len = strlen(input);
    // strip trailing \n off.
    if (len > 0 && input[len - 1] == '\n') {
        input[--len] = 0;
    }

    // abort on empty input
    if (len <= 0) {
        fprintf(stderr, "Invalid input - terminated.\n");
        exit(1);
    }

    if (len >= intoSize) {
        fprintf(stderr, "Invalid input - length was %u, limit is %u\n", len, intoSize - 1);
        exit(2);
    }

    strncpy(into, input, intoSize);
}

int main(int argc, const char* argv[])
{
    char eaf[10], initials[1], foo[10];
    report(eaf, initials, foo);

    load("Insert states of the optimized AFD", eaf, sizeof(eaf));
    report(eaf, initials, foo);

    load("Insert initial AFD state", initials, sizeof(initials));
    report(eaf, initials, foo);

    printf("eaf = %s\ninitials = %s\n", eaf, initials);

    return 0;
}

查看ideone here上的实时演示。

答案 1 :(得分:0)

scanf中的格式字符串很可能是罪魁祸首;您在%s之前有额外空间

变化:

scanf( " %s", eaf);

scanf( "%s", eaf);

适用于所有scanf

它没有将您的输入放入eaf,因为它正在寻找格式为“ blahblahblah ”的字符串(请注意开头的空格)而不是“ blahblahblah < /强>“

修改

忽略上述内容,

  

空格:任何空白字符都会触发扫描零个或多个空格字符。空白字符的数量和类型不需要在任何一个方向上匹配。

此外,您应该在i函数中初始化COMPARE(我不明白您是如何得到编译器的愤怒警告的),我运行您的代码时没有修改{ {1}}返回了正确的计数(就在strlen(eaf)之后)。