char数组C++中的输入字符串
Input string in char array C++
这是我的代码:
char A[10];
char B[5];
cin >> setw(10) >> A;
cin >> setw(5) >> B;
cout << A;
cout << B;
如果输入超过数组大小(例如:A
变量为 10),则程序不会提示我输入第二个数据。它一直走到最后并执行两个 "cout" 行。
输入:abcabcabcabcabcabc
(对于 A)
输出:abcabcabcabca
(13 space for char + 2 '\n')
预期输出:
abcabcabc
(对于 A)
dddd
(对于 B)
我想为两个变量输入数据,即使我为其中一个变量输入了太多字符
由于您使用的是 C++,因此您可以使用 string
string A,B;
cin>>A>>B;
在这里你可以扫描任意数量的字符。
如果您想读取具有固定限制的 C 字符串,最好的方法是使用 fgets
,它是标准 C++ 库的一部分。
你也可以使用iomanip
到setw
,像这样:
char A[10];
char B[15];
cin >> setw(10) >> A;
cin >> setw(15) >> B;
请注意,您返回的字符串长度将比您设置的宽度小一,因为 C 字符串需要空终止。
注意: 虽然这种 C 和 C++ 的混合可以工作,但您最好使用 std::string
作为一种更习惯于 C++ 的方法。不过,我知道这可能是一个学习练习,您不能在其中使用 std::string
。
在 C++ 中,您可以像下面这样进行操作
std::string A,B;
std::getline(std::cin,A);
std::getline(std::cin,B);
这避免了固定大小数组的任何陷阱,例如 char[10]
并读取整行。或者,您可以添加分隔符
const auto delim = '.'; // say
std::getline(std::cin,A,delim);
std::getline(std::cin,B,delim);
我认为没有允许多个分隔符的简单方法(即不自己编写代码)。
如果您想坚持使用 C 函数,您有几个选择。
第一个选项是利用 fgets
在它读取的字符串中包含换行符这一事实,但前提是它停止读取的原因是因为它到达了一行的末尾。您可以检查最后一个字符是否是换行符,如果不是,则丢弃输入中剩余的所有内容,包括下一个换行符:
int count;
fgets(A, 10, stdin);
count = strlen(A);
if (count == 9 && A[8] != '\n') {
do {} while (getc(stdin) != '\n');
}
fgets(B, 15, stdin);
printf("A: %s; B: %s\n", A, B);
如果您不想在字符串中使用换行符,请务必将其删除。您可能希望将过多的输入视为错误,而不是仅仅跳过额外的字符。
一个稍微简单的选择是使用 scanf
代替,但前提是您不想在每个变量的输入中允许空格:
int count;
scanf("%9s%n", A, &count);
if (count == 9) {
do {} while (!isspace(getc(stdin)));
}
scanf("%14s", B);
printf("A: %s; B: %s\n", A, B);
此 C 函数读取任意长度的行和 returns 新分配的内存块中指向它的指针(记住要 free()
它)。如果 keepNL
为真并且换行符(即不是 EOF)停止读取,则它包含在字符串的末尾。如果 len
不是 NULL
,则 *len
设置为行的长度,包括任何换行符。它使得读取带有 '[=16=]'
的行成为可能,而 strlen()
无法处理。
失败时,返回 NULL
而 *len
不变。如果 feof()
为真,则在读取任何字符之前到达 EOF(文件中不再有行)。如果 ferror()
为真,则发生 I/O 错误。如果 feof()
和 ferror()
都不为真,则内存耗尽。
注意内存块可能比字符串的长度要大。如果您需要节省内存,realloc()
自己 *len + 1U
。
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#define MIN_LINE_BUF ((size_t) 128U) /* >= 1 */
char *fgetline(size_t *len, FILE *stream, int keepNL) {
char *buf;
int c;
size_t i, size;
if (!(buf = malloc(size = MIN_LINE_BUF))) {
return NULL;
}
i = 0U;
while ((c = getc(stream)) != EOF) {
if (c != '\n' || keepNL) {
buf[i++] = (char) c;
if (i == size) {
char *newPtr;
if (size > (size_t) -1 - size
|| !(newPtr = realloc(buf, size <<= 1))) {
free(buf);
return NULL;
}
buf = newPtr;
}
}
if (c == '\n') {
break;
}
}
if ((c == EOF && i == 0U) || ferror(stream)) {
free(buf);
return NULL;
}
buf[i++] = '[=10=]';
if (len) {
*len = i;
}
return buf;
}
这是我的代码:
char A[10];
char B[5];
cin >> setw(10) >> A;
cin >> setw(5) >> B;
cout << A;
cout << B;
如果输入超过数组大小(例如:A
变量为 10),则程序不会提示我输入第二个数据。它一直走到最后并执行两个 "cout" 行。
输入:abcabcabcabcabcabc
(对于 A)
输出:abcabcabcabca
(13 space for char + 2 '\n')
预期输出:
abcabcabc
(对于 A)
dddd
(对于 B)
我想为两个变量输入数据,即使我为其中一个变量输入了太多字符
由于您使用的是 C++,因此您可以使用 string
string A,B;
cin>>A>>B;
在这里你可以扫描任意数量的字符。
如果您想读取具有固定限制的 C 字符串,最好的方法是使用 fgets
,它是标准 C++ 库的一部分。
你也可以使用iomanip
到setw
,像这样:
char A[10];
char B[15];
cin >> setw(10) >> A;
cin >> setw(15) >> B;
请注意,您返回的字符串长度将比您设置的宽度小一,因为 C 字符串需要空终止。
注意: 虽然这种 C 和 C++ 的混合可以工作,但您最好使用 std::string
作为一种更习惯于 C++ 的方法。不过,我知道这可能是一个学习练习,您不能在其中使用 std::string
。
在 C++ 中,您可以像下面这样进行操作
std::string A,B;
std::getline(std::cin,A);
std::getline(std::cin,B);
这避免了固定大小数组的任何陷阱,例如 char[10]
并读取整行。或者,您可以添加分隔符
const auto delim = '.'; // say
std::getline(std::cin,A,delim);
std::getline(std::cin,B,delim);
我认为没有允许多个分隔符的简单方法(即不自己编写代码)。
如果您想坚持使用 C 函数,您有几个选择。
第一个选项是利用 fgets
在它读取的字符串中包含换行符这一事实,但前提是它停止读取的原因是因为它到达了一行的末尾。您可以检查最后一个字符是否是换行符,如果不是,则丢弃输入中剩余的所有内容,包括下一个换行符:
int count;
fgets(A, 10, stdin);
count = strlen(A);
if (count == 9 && A[8] != '\n') {
do {} while (getc(stdin) != '\n');
}
fgets(B, 15, stdin);
printf("A: %s; B: %s\n", A, B);
如果您不想在字符串中使用换行符,请务必将其删除。您可能希望将过多的输入视为错误,而不是仅仅跳过额外的字符。
一个稍微简单的选择是使用 scanf
代替,但前提是您不想在每个变量的输入中允许空格:
int count;
scanf("%9s%n", A, &count);
if (count == 9) {
do {} while (!isspace(getc(stdin)));
}
scanf("%14s", B);
printf("A: %s; B: %s\n", A, B);
此 C 函数读取任意长度的行和 returns 新分配的内存块中指向它的指针(记住要 free()
它)。如果 keepNL
为真并且换行符(即不是 EOF)停止读取,则它包含在字符串的末尾。如果 len
不是 NULL
,则 *len
设置为行的长度,包括任何换行符。它使得读取带有 '[=16=]'
的行成为可能,而 strlen()
无法处理。
失败时,返回 NULL
而 *len
不变。如果 feof()
为真,则在读取任何字符之前到达 EOF(文件中不再有行)。如果 ferror()
为真,则发生 I/O 错误。如果 feof()
和 ferror()
都不为真,则内存耗尽。
注意内存块可能比字符串的长度要大。如果您需要节省内存,realloc()
自己 *len + 1U
。
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#define MIN_LINE_BUF ((size_t) 128U) /* >= 1 */
char *fgetline(size_t *len, FILE *stream, int keepNL) {
char *buf;
int c;
size_t i, size;
if (!(buf = malloc(size = MIN_LINE_BUF))) {
return NULL;
}
i = 0U;
while ((c = getc(stream)) != EOF) {
if (c != '\n' || keepNL) {
buf[i++] = (char) c;
if (i == size) {
char *newPtr;
if (size > (size_t) -1 - size
|| !(newPtr = realloc(buf, size <<= 1))) {
free(buf);
return NULL;
}
buf = newPtr;
}
}
if (c == '\n') {
break;
}
}
if ((c == EOF && i == 0U) || ferror(stream)) {
free(buf);
return NULL;
}
buf[i++] = '[=10=]';
if (len) {
*len = i;
}
return buf;
}