【发布时间】:2018-09-13 08:06:11
【问题描述】:
我编写了一个小程序作为示例来复制我遇到的问题。程序以这种方式获取和操作两行代码:
- 它用新行分隔行。
- 每一行由若干个字母和一个空格(在本例中为
' ')和一个数字组成。 - 它将字母复制到另一个字符串,然后添加
'\0'。 - 它将数字复制到另一个字符。
- 它打印字符串,其中是复制的字母和 int,其中是转换后的复制数字。
这是最小的程序:
#include <stdio.h>
#include <string.h>
void read(char *text)
{
// create and initialize the line holder
int k = 0;
char line[10];
line[0] = '\0';
for (int i = 0;text[i] != '\0';i++)
{
if (text[i] == '\n')
{
// k now points to the character right after the last assigned one, so put 0 in that place
line[k] = '\0';
// initialize data objects that will hold text and number
char letters[5];
letters[0] = '\0';
char val;
// step through the line, and stop if you 1. reached a blank or 2. reached the end of a line
int j = 0;
while (line[j] != ' ' && line[j] != '\t' && j <= (strlen(line) - 1))
{
printf("%d <= %ld = %d\n", j, strlen(line) - 1, j <= (strlen(line) - 1));
if (j == (strlen(line) - 1)) // reached the last character before reaching blank
return;
letters[j] = line[j];
j++;
}
letters[j] = '\0'; // where should be blank place 0
if (j + 1 == (strlen(line) - 1)) // if the next character is the last character, meaning that the character before the last one is blank
val = line[j + 1];
else // there is space in that is not one before the last character
return; // this is where read("\n") should stop, but withou entering the while loop!
printf("Word: %s\tVal: %d\n", letters, val - '0');
// empty the line holder
line[0] = '\0';
k = 0;
}
else
{
// place the ith text character into the kth line character and print them
line[k] = text[i];
printf("line[k] = %c\ttext[i] = %c\n", line[k], text[i]);
// increment k for the next turn
k++;
}
}
}
int main()
{
char *text = "ABCD 0\nEFGH 1\nIJKL 2\nMNOP 3\nQRST 4\nUVWX 5\nYZ 5\n";
read(text);
printf("---------------------------------\n");
read("\n");
return 0;
}
如果检测到错误,该程序也应该终止而不执行其工作。这些点由return 关键字和read(char *text) 函数中的cmets 指示。它们只有两个,所以我也将在这里描述它们:
第 28 行:如果检测到当前字符是最后一个字符,程序将停止扫描此行。由于最后一个字符应该始终以空格开头,这意味着我们在没有退出 while 循环的情况下到达了行尾(如果我们到达 ' ' 或 '\t' 就会发生这种情况)。
第 38 行:如果我们成功退出了 while 循环,则字符 j 与 line 的偏移应该是空白。那是因为我们在发现空白时退出了 while 循环(这也是因为我们以 line[j] = '\0' 结束 line)。这也意味着j+1 应该是一个数字,它是该行中的最后一个字符。如果不是这样,我们到达了不在数字之前的空白处,所以我们退出了函数。
那么,问题出在哪里?如您所见,我将两个字符串传递给
read(char *text) 函数。 read(char *text) 完美地操作和打印第一个字符串。对于第二个,只有"\n",这个功能不能很好地工作。我不明白的部分是我们进入了while循环,尽管条件j <= strlen(line) - 1)在text = "\n"时以某种方式返回1。您可以看到,通过运行程序,它会在第 26 行打印该信息。
【问题讨论】:
-
请注意,
strlen返回一个size_t值,即无符号。现在想想当strlen返回0并从中减去1时会发生什么...... -
你不能将你的函数命名为
read,因为已经有一个该名称的标准函数,即使你避免包含定义标准函数的头文件,这也会为编译器保留名称。 -
为什么不改用
j < strlen(line)? -
阅读how to debug small programs。启用所有警告和调试信息,例如
gcc -Wall -Wextra -g使用时GCC -
@PascalCuoq:你真的确定吗? IIRC
read是 POSIX 函数,而不是 C11 标准函数。但实际上你是完全正确的。给函数命名read是不合理的
标签: c