C 中的 For 循环未完全执行
For Loop in C not fully executing
似乎在处理拆分给定字符串的 for 循环内部,它只会在退出前执行两次,并且不会使用我放置在其中的 if 语句以及 isValid 函数中执行检查。我正在尝试对来自包含给定字符串的缓冲区的输入进行简单检查。如果我注释掉第一个 'printf' 语句下面的代码块,它将通过打印出每个标记化字符串来正确执行。保留它,它只会打印前两次迭代(i 为 0,1),然后不会发生其他任何事情。我似乎无法弄清楚为什么会这样。
这是我的代码:
void processRequest (int socket)
{
int n, i=0,error_code = 1;
char buffer[256], parsed_input[256];
char* token;
n = read(socket,buffer,255);
for (token = strtok(buffer, " "); i, token; token = strtok(NULL, " "),i++)
{
printf("Argument %d: %s\n", i,token);
if(i == 0 && (strcmp(token,"bye") == 0))
{
error_code = -5;
break;
}
else if(i == 0 && (strcmp(token,"terminate") == 0))
{
exit(0);
}
if((error_code = isValid(token, i)) != 1)
break;
}
}
还有 isValid 的实现:
int isValid(char* token, int i)
{
switch(i){
case 0:
if((strcmp(token,"add") == 0) || (strcmp(token,"subtract") == 0) || (strcmp(token,"multiply") == 0))
return 1;
else
return -1;
break;
case 1:
case 2:
case 3:
case 4:
if(isdigit(token))
return 1;
else
return -4;
break;
default:
return 1;
break;
}
}
此演示代码表明您的代码可以工作:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int isValid(char *token, int i);
void processRequest(void /*int socket*/);
void processRequest(void /*int socket*/)
{
int i = 0;
int error_code = 1;
char buffer[256] = "subtract 123 103 11 2 elephants cavorting";
char *token;
//int n = read(socket,buffer,255);
int n = strlen(buffer);
printf("[%.*s]\n", n, buffer);
for (token = strtok(buffer, " "); token; token = strtok(NULL, " "), i++)
{
printf("Argument %d: %s\n", i, token);
if (i == 0 && (strcmp(token, "bye") == 0))
{
error_code = -5;
break;
}
else if (i == 0 && (strcmp(token, "terminate") == 0))
{
exit(0);
}
if ((error_code = isValid(token, i)) != 1)
break;
printf("error_code = %d\n", error_code);
}
}
int isValid(char *token, int i)
{
switch (i)
{
case 0:
if ((strcmp(token, "add") == 0) ||
(strcmp(token, "subtract") == 0) ||
(strcmp(token, "multiply") == 0))
return 1;
else
return -1;
break;
case 1:
case 2:
case 3:
case 4:
if (isdigit(*token))
return 1;
else
return -4;
break;
default:
return 1;
break;
}
}
int main(void)
{
processRequest();
return 0;
}
样本运行:
[subtract 123 103 11 2 elephants cavorting]
Argument 0: subtract
error_code = 1
Argument 1: 123
error_code = 1
Argument 2: 103
error_code = 1
Argument 3: 11
error_code = 1
Argument 4: 2
error_code = 1
Argument 5: elephants
error_code = 1
Argument 6: cavorting
error_code = 1
您的代码不包含打印缓冲区中从套接字读取的内容的诊断信息 — 而且您没有向我们展示正在发送的内容。它还不能确保数据是一个以 null 结尾的字符串。
这表明问题更可能出在通过套接字读取的数据或调用此函数的代码中,而不是函数的主要部分。或者误用 isdigit()
的代码导致您的代码失败。您是否忽略了编译警告?如果你的编译器没有告诉你你滥用了 isdigit()
,你要么需要打开更多的警告,要么你需要一个更好的编译器。如果你想验证令牌中的数字是否完整,你必须更加努力,并且可能使用 strtol()
或 strtod()
或他们的亲戚之一(strtoimax()
,也许)。
似乎在处理拆分给定字符串的 for 循环内部,它只会在退出前执行两次,并且不会使用我放置在其中的 if 语句以及 isValid 函数中执行检查。我正在尝试对来自包含给定字符串的缓冲区的输入进行简单检查。如果我注释掉第一个 'printf' 语句下面的代码块,它将通过打印出每个标记化字符串来正确执行。保留它,它只会打印前两次迭代(i 为 0,1),然后不会发生其他任何事情。我似乎无法弄清楚为什么会这样。
这是我的代码:
void processRequest (int socket)
{
int n, i=0,error_code = 1;
char buffer[256], parsed_input[256];
char* token;
n = read(socket,buffer,255);
for (token = strtok(buffer, " "); i, token; token = strtok(NULL, " "),i++)
{
printf("Argument %d: %s\n", i,token);
if(i == 0 && (strcmp(token,"bye") == 0))
{
error_code = -5;
break;
}
else if(i == 0 && (strcmp(token,"terminate") == 0))
{
exit(0);
}
if((error_code = isValid(token, i)) != 1)
break;
}
}
还有 isValid 的实现:
int isValid(char* token, int i)
{
switch(i){
case 0:
if((strcmp(token,"add") == 0) || (strcmp(token,"subtract") == 0) || (strcmp(token,"multiply") == 0))
return 1;
else
return -1;
break;
case 1:
case 2:
case 3:
case 4:
if(isdigit(token))
return 1;
else
return -4;
break;
default:
return 1;
break;
}
}
此演示代码表明您的代码可以工作:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int isValid(char *token, int i);
void processRequest(void /*int socket*/);
void processRequest(void /*int socket*/)
{
int i = 0;
int error_code = 1;
char buffer[256] = "subtract 123 103 11 2 elephants cavorting";
char *token;
//int n = read(socket,buffer,255);
int n = strlen(buffer);
printf("[%.*s]\n", n, buffer);
for (token = strtok(buffer, " "); token; token = strtok(NULL, " "), i++)
{
printf("Argument %d: %s\n", i, token);
if (i == 0 && (strcmp(token, "bye") == 0))
{
error_code = -5;
break;
}
else if (i == 0 && (strcmp(token, "terminate") == 0))
{
exit(0);
}
if ((error_code = isValid(token, i)) != 1)
break;
printf("error_code = %d\n", error_code);
}
}
int isValid(char *token, int i)
{
switch (i)
{
case 0:
if ((strcmp(token, "add") == 0) ||
(strcmp(token, "subtract") == 0) ||
(strcmp(token, "multiply") == 0))
return 1;
else
return -1;
break;
case 1:
case 2:
case 3:
case 4:
if (isdigit(*token))
return 1;
else
return -4;
break;
default:
return 1;
break;
}
}
int main(void)
{
processRequest();
return 0;
}
样本运行:
[subtract 123 103 11 2 elephants cavorting]
Argument 0: subtract
error_code = 1
Argument 1: 123
error_code = 1
Argument 2: 103
error_code = 1
Argument 3: 11
error_code = 1
Argument 4: 2
error_code = 1
Argument 5: elephants
error_code = 1
Argument 6: cavorting
error_code = 1
您的代码不包含打印缓冲区中从套接字读取的内容的诊断信息 — 而且您没有向我们展示正在发送的内容。它还不能确保数据是一个以 null 结尾的字符串。
这表明问题更可能出在通过套接字读取的数据或调用此函数的代码中,而不是函数的主要部分。或者误用 isdigit()
的代码导致您的代码失败。您是否忽略了编译警告?如果你的编译器没有告诉你你滥用了 isdigit()
,你要么需要打开更多的警告,要么你需要一个更好的编译器。如果你想验证令牌中的数字是否完整,你必须更加努力,并且可能使用 strtol()
或 strtod()
或他们的亲戚之一(strtoimax()
,也许)。