我对编码很新,目前正在学校和C一起开设编程课程。我们获得了一项任务,我在第一部分遇到了一些困难。我们正在学习如何使用字符串处理库(stdlib.h),分配的目的是从键盘输入多行文本。教练建议我们使用二维数组来做到这一点,但我有点卡住了。这是我写的代码:
int main(void) {
char string[3][SIZE];
int i, j;
int c;
printf("Enter three lines of text:\n");
for (i = 0; i < 3; i++) {
j = 0;
while ((j < SIZE) && (c = getchar() != '\n')) {
string[i][j] = c;
j++;
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < SIZE; j++) {
printf("%c", string[i][j]);
}
printf("\n");
}
return 0;
}
我想提出的一些观点是我使用getchar()函数一次接收输入一个字符,还有第二个for循环我打算打印存储在每一行中的每行文本字符串数组。
输入是三行的任何文本字符串,例如:
Hi my name is John.\n
I am from the US\n
and I'm a student.
这是当前输出的样子:
Enter three lines of text:
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr...
我期待的输出是:
Enter three lines of text:\n
Hi my name is John.\n
I'm from the US\n
and am a student.
任何提示或建议将不胜感激。谢谢!
答案 0 :(得分:1)
注意:我在OP澄清他们必须使用getchar
之前写了这个答案。
要一次阅读整行,请使用fgets
。要一次打印整个字符串,请使用%s
格式的printf
。
#include <stdio.h>
int main(void) {
// No need to define a SIZE constant.
// Because it's stack allocated we can its size.
char strings[3][100];
printf("Enter three lines of text:\n");
for ( int i = 0; i < 3; i++) {
// Reads one line, up to the size of `strings[i]`, from stdin.
fgets( strings[i], sizeof(strings[i]), stdin );
}
for ( int i = 0; i < 3; i++) {
// Print each string and its line number.
printf("Line %d: %s\n", i, strings[i]);
}
return 0;
}
这不是读取输入的最佳模式。您将很快了解到固定内存大小和阅读输入效果不佳。为了将来参考,它会更像是这样。
#include <stdio.h>
#include <string.h>
int main(void) {
// A list to store 3 strings, but no memory for the strings themselves.
char *strings[3];
printf("Enter three lines of text:\n");
// A line buffer that's sufficiently large.
// This will be reused.
char line[4096];
for ( int i = 0; i < 3; i++) {
// Read into the large line buffer.
fgets( line, sizeof(line), stdin );
// Copy the string into a buffer that's just big enough.
strings[i] = strdup( line );
}
for ( int i = 0; i < 3; i++) {
printf("Line %d: %s\n", i, strings[i]);
}
return 0;
}
这会分配一个大的行缓冲区来进行读取,然后将其用strdup
读取的内容复制到大小合适的内存中。这使得您可以阅读非常长的输入行,而不会浪费大量内存,如果它们非常短。
请注意,strdup()
不是C标准库的一部分,但它是POSIX规范的一部分。任何主要的编译器都会拥有它,并且编写自己的编译器很容易。
答案 1 :(得分:1)
首先让我赞扬你用C语言开始学习的事实。这是最难学的语言(更好的只是装配本身) - 你将完全理解事物的运作方式,你不会如果从一些基于C语言编写的语言(如Java和Python)开始。 但这是一条艰难而漫长的道路,值得这样做。
关于代码:有很多事情要做,你已经制作了很多有趣的错误,每隔一段时间就可以重现不同的有趣事物并运行它。
首先:为了使你的代码以某种方式工作,你只需要添加括号:
UICollectionView
在C中,一切都是二进制(或整数,取决于你如何看待),默认绑定是右边的op1 b op2 c op3 d .. 第一个op3被评估为c op3 d = r1,然后你有一个op1 b op2 r1,依此类推。 因此,您将getchar()的值与字符'\ n'的值进行比较 - 它们不相等,因此您得到TRUE(值1)并将其存储在局部变量c中。
接下来,由于初始化数组的方式,您仍然会遇到一些问题:
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 0
layout.headerReferenceSize = .zero
layout.sectionInset = .zero
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .green
cv.dataSource = self
cv.delegate = self
cv.contentInset = .zero
return cv
}()
它所做的只是“内部”3 * SIZE * sizeof(char)字节处理地址空间到标记为“字符串”的事物。但是这并没有清除所有上一次(你的程序,甚至之前)的遗留物在这些字节上,所以如果你的程序中的SIZE = = 100并且你曾经将你的信用卡存储在一个真实的地址内存中(RAM)映射到程序存储器的那个区域,当你用printf打印时,你会看到你的信用卡 - 如果你没有覆盖那300个字节。
这可以帮助您查看它:
while ((j < SIZE) && ((c = getchar()) != '\n')) {
还要注意getchar()在输入和换行时可能会表现糟糕 - 这取决于你是否在输入(换行符)之前将缓冲区输入控制台输入到你的程序之前。更多How to avoid press enter with any getchar()