gpt4 book ai didi

c - 在 C 中读取未定义长度的字符串

转载 作者:太空狗 更新时间:2023-10-29 16:57:41 24 4
gpt4 key购买 nike

首先(一如既往)我想为我的英语道歉,它可能不够清楚。

我不太擅长 C 编程,我被要求读取一个未定义长度的“字符串”输入。

这是我的解决方案

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *newChar();
char *addChar(char *, char);
char *readLine(void);

int main() {
char *palabra;
palabra = newChar();

palabra = readLine();
printf("palabra=%s\n", palabra);

return 0;
}

char *newChar() {
char *list = (char *) malloc(0 * sizeof (char));
*list = '\0';
return list;
}

char *addChar(char *lst, char num) {
int largo = strlen(lst) + 1;
realloc(&lst, largo * sizeof (char));
*(lst + (largo - 1)) = num;
*(lst + largo) = '\0';
return lst;
}

char *readLine() {
char c;
char *palabra = newChar();

c = getchar();
while (c != '\n') {
if (c != '\n') {
palabra = addChar(palabra, c);
}
c = getchar();
}
return palabra;
}

拜托,如果你能帮助我,告诉我这是个好主意还是给我一些其他想法(并告诉我这是否是指针的“正确”用法),我将不胜感激。

提前致谢


编辑: 嗯,谢谢你的回答,它们非常有用。现在我发布编辑过的(我希望更好的)代码,也许对 C 的新手(比如我)有用并再次得到反馈。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void reChar(char **, int *);
void readLine(char **, int *);

int main() {
char *palabra = NULL;
int largo = 0;

reChar(&palabra, &largo);
readLine(&palabra, &largo);
printf("palabra=%s\n", palabra, largo);

system("pause");
return 0;
}

void reChar(char **lst, int *largo) {
(*largo) += 4;
char *temp = (char*) realloc(*lst, (*largo) * sizeof (char));

if (temp != NULL) {
*lst = temp;
} else {
free(*lst);
puts("error (re)allocating memory");
exit(1);
}
}

void readLine(char **lst, int *largo) {
int c;
int pos = 0;

c = getchar();
while (c != '\n' && c != EOF) {
if ((pos + 1) % 4 == 0) {
reChar(lst, largo);
}
(*lst)[pos] =(char) c;
pos++;
c = getchar();
}
(*lst)[pos] = '\0';
}

附言:

  • 似乎足以减缓“palabra”的大小。

  • 我不确定将 getchar() 捕获到 int 然后将其转换为 char 是否正确处理方法 EOF pitfall

最佳答案

  1. 查找POSIX的定义getline() .

  2. 请记住,您需要从 realloc() 中捕获返回值;不能保证新内存块的起始位置与旧内存块相同。

  3. 知道 malloc(0) 可能返回一个空指针,或者它可能返回一个不可用的非空指针(因为它指向零字节的内存)。

  4. 当 list 指向已分配内存的零字节时,您不能写 '*list = '\0';;你没有在那里写的权限。如果返回 NULL,则很可能会得到核心转储。在任何情况下,您都在调用未定义的行为,这是“一个坏主意™”。 ( Thanks )

  5. main() 中的 palabra = newChar(); 会泄漏内存 - 假设您已解决已讨论的其他问题。

    <
  6. readLine() 中的代码没有考虑在获取换行符之前获取 EOF 的可能性;这很糟糕,当内存分配(最终)失败时会导致核心转储。

  7. 您的代码会表现出很差的性能,因为它一次分配一个字符。通常,您应该一次分配多于一个的额外字符;从大约 4 个字节的初始分配开始,每次需要更多空间时将分配加倍可能会更好。保持初始分配较小,以便正确测试重新分配代码。

  8. getchar() 的返回值是一个int,而不是一个char。在大多数机器上,它可以返回 256 个不同的正字符值(即使 char 是有符号类型)和一个单独的值 EOF,它不同于所有 char 值. (如果机器的每个字节大于 8 位,则标准允许它返回超过 256 个不同的字符。)(Thanks)C99 标准 §7.19.7.1 说 fgetc() :

    If the end-of-file indicator for the input stream pointed to by stream is not set and a next character is present, the fgetc function obtains that character as an unsigned char converted to an int and advances the associated file position indicator for the stream (if defined).

    (重点添加。)它根据 getc() 定义 getchar(),并根据 getc() 定义 getc() fgetc().

  9. (借用:Thanks)。 realloc() 的第一个参数是指向当前分配内存开始的指针,而不是指向当前分配内存开始的指针。如果您没有从中收到编译警告,则说明您没有在编译器上设置足够多的警告进行编译。您应该将警告调到最大。您应该注意编译器警告 - 它们通常表示您的代码中存在错误,尤其是在您仍在学习该语言时。

  10. 在您知道已到达行尾(或输入末尾)之前,保持字符串不带空终止符通常更容易。当没有更多的字符要读取时(暂时),然后附加 null 以便字符串在返回之前正确终止。这些函数在读取时不需要字符串正确终止,只要您跟踪您在字符串中的位置即可。不过,请确保您始终有足够的空间将 NUL '\0' 添加到字符串的末尾。

参见 Kernighan & Pike 'The Practice of Programming'对于很多相关的讨论。我也觉得马奎尔'Writing Solid Code'提供了相关的建议,尽管它有点过时了。但是,您应该知道有些人会痛斥这本书。因此,我推荐 TPOP 而不是 WSC(但亚马逊的 WSC 起价为 0.01 美元 + p&p,而 TPOP 起价为 20.00 美元 + p&p——这可能是市场的说法)。


<支持>TPOP 之前在 http://plan9.bell-labs.com/cm/cs/tpophttp://cm.bell-labs.com/cm/cs/tpop但现在 (2015-08-10) 都坏了。另见维基百科 TPOP .

关于c - 在 C 中读取未定义长度的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3598351/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com