简体   繁体   English

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

[英]What does the ? mean when outputting a string using printf and is strcmp supposed to return a zero for matches (in 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): 所以我的问题是在输出中获取应该出现的字符的问号,而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

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. 我是C语言的新手,我迷失了为何获得该输出。 Hints please. 请提示。

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: 您可以使用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{}()*+=,;");
    }
}

Note that I use '\\n' character in delimiters string because fgets function reads line into buffer that will include '\\n' at the end. 请注意,我在定界符字符串中使用了'\\n'字符,因为fgets函数将行读入缓冲区的末尾,该缓冲区中将包含'\\n'

Content of file a.txt : 文件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

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. 您应该将功能拆分为几个较小的功能,甚至已经在步骤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. 现在,由于您正在重用之前声明的变量,因此在执行第四步时可能会遇到count不等于== 0的问题。 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 eg 当您进行这样的词法分析时,通常最好使用状态机,例如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;

if you don't have a debugger include assert.h and put asserts in your code to make sure all assumptions are caught ie assert( count == 0 ); 如果您没有调试器,则包含assert.h并将asserts放入代码中,以确保捕获所有假设,即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). 复制时使用strcpy或更好的strncpy而不是memcpy,当strcpy -family遇到\\ 0时,它会停止复制,这会更有效(它也会复制\\ 0)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM