【问题标题】:readLine() and readLines() implementationreadLine() 和 readLines() 实现
【发布时间】:2021-05-17 16:29:07
【问题描述】:

我需要在 C 中创建 2 个单独的函数 readLine() 和 readLines()。第一个必须返回指向输入字符串的指针,第二个应该返回输入字符串的指针数组。 readLines() 以换行符终止。我遇到了一些错误,可能与内存有关,有时可以,有时不能。代码如下:

char* readLine() {
   char pom[1000];
   gets(pom);
   char* s = (char*)malloc(sizeof(char) * strlen(pom));
   strcpy(s, pom);

   return s;
}

这里是 readLines()

char** readLines() {
   char** lines = (char**)malloc(sizeof(char*));
   int i = 0;
   do {
       char pom[1000];
       gets(pom);
       lines[i] = (char*)malloc(sizeof(char) * strlen(pom));
       strcpy(lines[i], pom);
       i++;
   } while (strlen(lines[i - 1]) != 0);

   return lines;
}

总的来说,我把这些函数称为

char* p = readLine();
char** lines = readLines();

【问题讨论】:

  • "readLines() is terminated with a new line character" -- 这是什么意思?这是否意味着函数readLines 应该继续读取直到找到一个空行?或者这是否意味着readLines 返回的数组应该包含一个只包含换行符的空字符串,以便标记数组的结尾?还是两者都有?
  • 这意味着它应该继续阅读,直到找到一个空字符串。该函数返回的是输入中空行之前的字符串数组。谢谢下面的回答,我去看看真正的qucik。
  • 函数main应该如何知道readLines返回了多少行?函数readLines 是否应该用包含值NULL 的指针标记数组的结尾?
  • 我们不能只遍历行并检查 strlen(lines[i]) == 0。然后我们知道它是空行吗?考虑到数组中有一个空行。
  • 是的,这是可能的。然而,使用包含值NULL 的指针来标记数组的结尾更常见(也更有效)。

标签: c string pointers


【解决方案1】:

使用malloc为字符串分配内存时,应该为整个字符串分配足够的内存,包括终止空字符

在您的情况下,strcpy 将导致 buffer overflow,因为目标缓冲区不够大。

你应该换行

char* s = (char*)malloc(sizeof(char) * strlen(pom));

char* s = (char*)malloc( sizeof(char) * (strlen(pom)+1) );

换行

lines[i] = (char*)malloc(sizeof(char) * strlen(pom));

lines[i] = (char*)malloc( sizeof(char) * (strlen(pom)+1) );

还有一行

char** lines = (char**)malloc(sizeof(char*));

是错误的,因为它只为单个指针分配了足够的内存。每行需要一个指针。不幸的是,您事先不知道会有多少行,所以您也不知道需要多少指针。但是,您可以根据需要使用函数realloc 调整缓冲区的大小。

虽然与您的问题无关,但值得注意的是函数gets已从ISO C标准中删除,不应再使用。建议改用fgets。有关更多信息,请参阅此问题:Why is the gets function so dangerous that it should not be used?

另外,在 C 中,没有必要强制转换 malloc 的返回值。这仅在 C++ 中是必需的。有关更多信息,请参阅此问题:Do I cast the result of malloc?

在您的代码中,您首先使用语句i++; 递增i,然后通过减去1 重构i 的先前值:

while (strlen(lines[i - 1]) != 0);

这是不必要的麻烦。最好写

while (strlen(lines[i++]) != 0);

并删除i++; 行。这样,您不再需要减去 1

【讨论】:

    猜你喜欢
    • 2014-07-04
    • 1970-01-01
    • 2022-12-05
    • 2019-05-23
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    相关资源
    最近更新 更多