gpt4 book ai didi

c - 全行输入的极度麻烦。 C程序设计语言

转载 作者:行者123 更新时间:2023-12-04 11:30:23 26 4
gpt4 key购买 nike

让全行输入工作是我最疯狂的时刻。我会解释我的问题。我需要从键盘输入的用户那里得到一整行输入,包括一个空格。简单吧?错了!

我的目标

将带有空格的多个字符串存储到变量中。如果它有所作为,我想让变量等于 char 指针。因此,一旦我从 tempString 获得输入,我想将其设置为 char 指针。像这样:

char *variable1, *variable2;
//get user input
variable1 = tempString;
//get more user input
variable 2 = tempString;
//etc etc etc

这是我尝试过的。

先试试

char tempString[100];
scanf("%s", &tempString);
printf("%s", tempString);

无效:scanf 将在空白处停止读取,因此“Example String”最终将变成“Example”。

第二次尝试

所以我做了更多的研究。我以为我找到了神奇的修复方法。

char tempSTring[100];
fgets(tempString, 100, stdin);
printf("%s", tempString);

最初这是可行的。然而,存在一个巨大的问题。我需要让用户输入大约 8 个输入。这意味着我必须使用这样的命令 8 次。问题是程序经常跳过 fgets 命令。如果我之前使用了 scanf,不知何故 \n 字符会卡在输入流中,并自动输入 fgets,满足其 stdin input,然后不提示用户输入。

第三次尝试

在考虑 fgets 可能是我的变通解决方案之后,我尝试了一些技巧。

char tempSTring[100];
getc(stdin);
fgets(tempString, 100, stdin);
printf("%s", tempString);

我尝试添加此 getc(stdin) 行。它适用于我的大部分程序。它吸收流中留下的 \n 字符。当它这样做时,很好,它起作用了。但有时,由于某种原因,\n 没有留在流中,并且在调试时,它看起来像 getc(stdin) 正在请求用户输入,所以它会暂停我的程序以请求输入。

问题

这些对我不起作用。

  • 我应该如何完成这项简单的任务?

最佳答案

要从一个文件中读取(最多)8 行,您可以使用这些解决方案中的任何一种。我拒绝使用变量 char *variable1, *variable2, …; — 这是一个试图转义的数组。

POSIX getline()

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

int main(void)
{
enum { MAX_LINES = 8 };
char *lines[MAX_LINES];
int index = 0;
char *buffer = 0;
size_t buflen = 0;

while (index < MAX_LINES && getline(&buffer, &buflen, stdin) != -1)
{
lines[index++] = buffer;
buffer = 0;
buflen = 0;
}
free(buffer); // Space may be allocated before EOF is detected

for (int i = 0; i < index; i++)
printf("%d: %s", i, lines[i]);

return 0;
}

如果 getline() 分配内存失败,它将报告错误,因此无需进行显式错误检查。

标准 C fgets()

代码使用 strdup() ,另一个 POSIX 函数。它不是标准 C 的一部分(尽管它被广泛使用)。实现起来很简单。

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

int main(void)
{
enum { MAX_LINES = 8 };
char *lines[MAX_LINES];
int index = 0;
char buffer[4096];

while (index < MAX_LINES && fgets(buffer, sizeof(buffer), stdin) != 0)
{
if ((lines[index] = strdup(buffer)) == 0)
break;
index++;
}

for (int i = 0; i < index; i++)
printf("%d: %s", i, lines[i]);

return 0;
}

循环中的测试允许 strdup() 分配内存失败的可能性。

注意事项

上述两种解决方案都将换行符保留在输入字符串的末尾。如果你不想这样,你可以用:

lines[i][strcspn(lines[i], "\r\n")] = '\0';

这会用空字节覆盖回车符或换行符,转换 DOS 或 Unix 行结尾。然后,您需要调整假定字符串包含换行符的打印。请注意,即使字符串中没有回车符或换行符,显示的表达式也能正常工作。

fgets() 解决方案将在 4095 个字符处换行,将其余部分作为“下一行”读取。如果这 Not Acceptable ,您可以使用多种策略。

  1. 您可以检测是否有换行符并安排分配更多内存并将行的下一部分读入额外内存,重复直到遇到换行符或 EOF。
  2. 您可以读取到换行符或 EOF 之前的剩余字符:

    int c;
    while ((c = getchar()) != EOF && c != '\n')
    ;

实现strdup()

如果由于某种原因您的系统没有strdup() 的实现,您可以创建一个代理:

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

char *strdup(const char *old_str)
{
assert(old_str != 0);
size_t old_len = strlen(old_str) + 1;
char *new_str = malloc(old_len);
if (new_str != 0)
memmove(new_str, old_str, old_len);
return new_str;
}

关于c - 全行输入的极度麻烦。 C程序设计语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39543155/

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