Что это? имеется в виду при выводе строки с использованием printf и должен ли strcmp возвращать ноль для совпадений (в C)?
Дело в том, что он должен прочитать это из файла:
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, и я заблудился относительно того, почему я получаю этот вывод. Подсказки, пожалуйста.
2 ответа
Из того, что я понимаю, вы просто хотите прочитать строку из входного файла и разбить ее на токены. Вы можете использовать функцию 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
Ваш код немного сложен для чтения - по крайней мере, четвертая часть (несмотря на комментарии), потому что он слишком длинный.
Вы должны разделить свою функцию на несколько более мелких, у вас даже есть структура на шаге 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).