的作用是什么?意思是当使用 printf 输出字符串时,strcmp 是否应该为匹配返回零(在 C 中)?

发布于 2025-01-07 22:49:51 字数 4645 浏览 1 评论 0原文

硬件的要点是它应该从文件中读取这个:

int func(int arg) { int x = 7; char c = 'a'; arg = x + c; return arg; }

并输出这个:

func, arg, x, c
//or optionally also the next line
int, char, return

所以我的问题是在我的输出上为应该出现的字符获取问号,并且 strcmp 不会为我的 if 语句返回零,这需要它工作(注意:我有很多注释和 printf 来帮助我找出哪里出错了):

while((d=fgetc(function_file)) != EOF) {
    //start by checking for any defines and just looping until a new line character comes up
    if( d == '#')
        flag = true;

    if((d == '\n') && (flag)){
        //flag which says if I am searching for a newline but only after a define/include 
        //was found will I say the flag is not needed anymore to allow normal parsing
        flag = false;
    } //end of check for a define function

    if( (flag == false) && (d != '#') ) {

        //this is where the main chunk of code goes to do all the parsing
        if((d != ' ') && (d != '\t') && (d !='\n') && (d != '{') && (d != '}') && (d != '(') && (d != ')') && (d != '*') && (d != '=') && (d != '+')) {

            printf("Character read is : %c\n", d);
            start = true;
            temp[count] = c;
            count++;
        }


    }//end of main chunk of code
        if((start == true) && ((d == ' ') || (d == '(') || (d == ')') || (d == '{') || (d == '}'))) {
            //end a string and compare it hear
            if(match == false) {
            temp[count] = '\0';
        printf("String: %s\n", temp);//*********************************DEBUGGING***********

            start = false;
            int compare;
            for(compare = 0; compare < key_counter; compare++) {
                int optimus;
                optimus = strcmp(keywords[compare], temp); //************** ONE OF THE ERRORS IS HERE***************************************?
                if(optimus == 0){
                    //printf("this is actually runnning");//*********************************DEBUGGING***********
                    int len = strlen(temp);
                    bizarro_keywords[bizarro_key_counter] = (char *)malloc(sizeof(char) * (len +1));
                    memcpy(bizarro_keywords[bizarro_key_counter], temp, len +1);
                    printf("\nWhats inside bizarro_key_counter right after it is allocated memory: %s", bizarro_keywords[bizarro_key_counter]);
                    bizarro_key_counter++;
                    match = true;
                }

            }

            int x;
            for(x = 0; x < count; x++)
                temp[x] = '\0';
            count = 0;


        } else { //if match equals true just grab the next available string 
            //printf("is this one ever running?");
            temp[count] = '\0';
            start = false;
            printf("String: %s\n", temp);

                    int len = strlen(temp);
                    identifiers[iden_counter] = (char *)malloc(sizeof(char) * (len +1));
                    memcpy(identifiers[iden_counter], temp, len +1);
                    iden_counter++;
                    match = false;



                    int x;
                    for(x = 0; x < count; x++)
                        temp[x] = '\0';
                    count = 0;

            }   
        }

}//end of while loop for reading the whole file

这是我的输出:

Character read is : i
Character read is : n
Character read is : t
String: ???
Character read is : f
Character read is : u
Character read is : n
Character read is : c
String: ????
Character read is : i
Character read is : n
Character read is : t
String: ???
Character read is : a
Character read is : r
Character read is : g
String: ???
Character read is : i
Character read is : n
Character read is : t
String: ???
Character read is : x
String: ?
Character read is : 7
Character read is : ;
String: ??
Character read is : c
Character read is : h
Character read is : a
Character read is : r
String: ????
Character read is : c
String: ?
Character read is : '
Character read is : a
Character read is : '
Character read is : ;
String: ????
Character read is : a
Character read is : r
Character read is : g
String: ???
Character read is : x
String: ?
Character read is : c
Character read is : ;
String: ??
Character read is : r
Character read is : e
Character read is : t
Character read is : u
Character read is : r
Character read is : n
String: ??????
Character read is : a
Character read is : r
Character read is : g
Character read is : ;
String: ????

我是 C 新手,我不知道为什么会得到这个输出。请提示。

Point of HW is it should read this from a file:

int func(int arg) { int x = 7; char c = 'a'; arg = x + c; return arg; }

and output this:

func, arg, x, c
//or optionally also the next line
int, char, return

So my issue is on getting question marks on my output for characters that should be appearing, and strcmp is not returning a zero for my if statement which requires it to work (note: I have a lot of comments and printf's to help me figure out where I am going wrong):

while((d=fgetc(function_file)) != EOF) {
    //start by checking for any defines and just looping until a new line character comes up
    if( d == '#')
        flag = true;

    if((d == '\n') && (flag)){
        //flag which says if I am searching for a newline but only after a define/include 
        //was found will I say the flag is not needed anymore to allow normal parsing
        flag = false;
    } //end of check for a define function

    if( (flag == false) && (d != '#') ) {

        //this is where the main chunk of code goes to do all the parsing
        if((d != ' ') && (d != '\t') && (d !='\n') && (d != '{') && (d != '}') && (d != '(') && (d != ')') && (d != '*') && (d != '=') && (d != '+')) {

            printf("Character read is : %c\n", d);
            start = true;
            temp[count] = c;
            count++;
        }


    }//end of main chunk of code
        if((start == true) && ((d == ' ') || (d == '(') || (d == ')') || (d == '{') || (d == '}'))) {
            //end a string and compare it hear
            if(match == false) {
            temp[count] = '\0';
        printf("String: %s\n", temp);//*********************************DEBUGGING***********

            start = false;
            int compare;
            for(compare = 0; compare < key_counter; compare++) {
                int optimus;
                optimus = strcmp(keywords[compare], temp); //************** ONE OF THE ERRORS IS HERE***************************************?
                if(optimus == 0){
                    //printf("this is actually runnning");//*********************************DEBUGGING***********
                    int len = strlen(temp);
                    bizarro_keywords[bizarro_key_counter] = (char *)malloc(sizeof(char) * (len +1));
                    memcpy(bizarro_keywords[bizarro_key_counter], temp, len +1);
                    printf("\nWhats inside bizarro_key_counter right after it is allocated memory: %s", bizarro_keywords[bizarro_key_counter]);
                    bizarro_key_counter++;
                    match = true;
                }

            }

            int x;
            for(x = 0; x < count; x++)
                temp[x] = '\0';
            count = 0;


        } else { //if match equals true just grab the next available string 
            //printf("is this one ever running?");
            temp[count] = '\0';
            start = false;
            printf("String: %s\n", temp);

                    int len = strlen(temp);
                    identifiers[iden_counter] = (char *)malloc(sizeof(char) * (len +1));
                    memcpy(identifiers[iden_counter], temp, len +1);
                    iden_counter++;
                    match = false;



                    int x;
                    for(x = 0; x < count; x++)
                        temp[x] = '\0';
                    count = 0;

            }   
        }

}//end of while loop for reading the whole file

This is my output:

Character read is : i
Character read is : n
Character read is : t
String: ???
Character read is : f
Character read is : u
Character read is : n
Character read is : c
String: ????
Character read is : i
Character read is : n
Character read is : t
String: ???
Character read is : a
Character read is : r
Character read is : g
String: ???
Character read is : i
Character read is : n
Character read is : t
String: ???
Character read is : x
String: ?
Character read is : 7
Character read is : ;
String: ??
Character read is : c
Character read is : h
Character read is : a
Character read is : r
String: ????
Character read is : c
String: ?
Character read is : '
Character read is : a
Character read is : '
Character read is : ;
String: ????
Character read is : a
Character read is : r
Character read is : g
String: ???
Character read is : x
String: ?
Character read is : c
Character read is : ;
String: ??
Character read is : r
Character read is : e
Character read is : t
Character read is : u
Character read is : r
Character read is : n
String: ??????
Character read is : a
Character read is : r
Character read is : g
Character read is : ;
String: ????

I am new to C, and I am lost as to why I am getting that output. Hints please.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一绘本一梦想 2025-01-14 22:49:51

据我了解,您只想从输入文件中读取行并将其拆分为令牌。您可以使用 strtok 函数而不是从文件中读取字符:

char* keywords[] = { "int", "char", "return" };
int i = 0, j, keywordsCount = 3;
FILE* f = fopen("a.txt", "r");
char line[1000], *token;
while (fgets(line, 1000, f) != NULL) // read line
{
    char* token = strtok(line, " \t\n{}()*+=,;");
    while (token != NULL)
    {
        printf("String %d:%s", i++, token);

        for (j = 0; j < keywordsCount; ++j)
            if (strcmp(token, keywords[j]) == 0)
            {
                printf(" <-- Look, it's keyword!");
                break; // breaks for, not while
            }

        putchar('\n');
        token = strtok(NULL, " \t\n{}()*+=,;");
    }
}

请注意,我在分隔符字符串中使用 '\n' 字符,因为 fgets 函数将行读入缓冲区,该缓冲区将在末尾包含 '\n'

文件a.txt的内容:

int func(int arg) { int x = 7; char c = 'a'; arg = x + c; return arg; }

输出:

String 0:int <-- Look, it's keyword!
String 1:func
String 2:int <-- Look, it's keyword!
String 3:arg
String 4:int <-- Look, it's keyword!
String 5:x
String 6:7
String 7:char <-- Look, it's keyword!
String 8:c
String 9:'a'
String 10:arg
String 11:x
String 12:c
String 13:return <-- Look, it's keyword!
String 14:arg

From what I understand you just want to read line from the input file and split it into tokens. You could use strtok function instead of reading characters from the file:

char* keywords[] = { "int", "char", "return" };
int i = 0, j, keywordsCount = 3;
FILE* f = fopen("a.txt", "r");
char line[1000], *token;
while (fgets(line, 1000, f) != NULL) // read line
{
    char* token = strtok(line, " \t\n{}()*+=,;");
    while (token != NULL)
    {
        printf("String %d:%s", i++, token);

        for (j = 0; j < keywordsCount; ++j)
            if (strcmp(token, keywords[j]) == 0)
            {
                printf(" <-- Look, it's keyword!");
                break; // breaks for, not while
            }

        putchar('\n');
        token = strtok(NULL, " \t\n{}()*+=,;");
    }
}

Note that I use '\n' character in delimiters string because fgets function reads line into buffer that will include '\n' at the end.

Content of file a.txt:

int func(int arg) { int x = 7; char c = 'a'; arg = x + c; return arg; }

Output:

String 0:int <-- Look, it's keyword!
String 1:func
String 2:int <-- Look, it's keyword!
String 3:arg
String 4:int <-- Look, it's keyword!
String 5:x
String 6:7
String 7:char <-- Look, it's keyword!
String 8:c
String 9:'a'
String 10:arg
String 11:x
String 12:c
String 13:return <-- Look, it's keyword!
String 14:arg
硪扪都還晓 2025-01-14 22:49:51

您的代码有点难以阅读 - 至少第四部分(尽管有注释),因为它太长了。

您应该将您的函数拆分为几个较小的函数,您甚至已经具备了步骤 1-4 的结构。现在,由于您正在重用之前声明的变量,因此当您进入第四步时,可能会出现诸如 count 不 == 0 之类的问题。因为有这么多的曲折,所以当你进行这样的词法分析时,很难看到问题,

所以通常最好使用状态机,switch 语句对此很有用,例如,

typedef enum { Idle, Include , ... } states_t;
states_t state=Idle;

switch (state)
{
   case Idle:
      switch ( d )
      { 
         case '#':
           state = Include;
           break;
     ...
     break;
   case Include:
     ...
     break;

      break;

如果你没有调试器,则包含assert.h并将断言放入代码中以确保捕获所有假设,即在第四步之前 assert( count == 0 ); 可能是一件好事。

复制时使用 strcpy 或更好的 strncpy 而不是 memcpy,strcpy 系列在遇到 \0 时停止复制,这有点多有效(它也复制 \0)。

Your code is a bit difficult to read - at least part four (despite the comments) because it is just too long.

You should split up your function into several smaller ones, you even already have the structure in place step 1-4. Now since you are reusing variables declared before there may sneak in issues like count not being == 0 when you get to step four. since there are so many twist and turns its a bit difficult to see the problem

when you such lexical analysis it is often better to use a state machine, switch statements are good for this e.g.

typedef enum { Idle, Include , ... } states_t;
states_t state=Idle;

switch (state)
{
   case Idle:
      switch ( d )
      { 
         case '#':
           state = Include;
           break;
     ...
     break;
   case Include:
     ...
     break;

      break;

if you don't have a debugger include assert.h and put asserts in your code to make sure all assumptions are caught i.e. assert( count == 0 ); before step four may be a good thing.

use strcpy or better strncpy instead of memcpy when copying, the strcpy-family stops to copying when it encounters a \0 which is a bit more effective (it copies the \0 as well).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文