我有这个字母和数字序列,其中字母总是这四个:s,S,m,M。数字可以有任何值。由于没有给出序列的大小,我只是不能使用 for循环,所以我决定使用while循环,但是我遇到了打破循环的问题。
一些输入示例是:
12 s 80 s 3 m 12 M 240 S 8 m 30 s 240 s 1440 S 8 m 18 s 60 M
5 m 120 s 30 s 360 S 6 M 5 s 42 S 36 M 8 m 66 M 3240 S 14 m
到目前为止,这是我的代码:
#include <stdio.h>
int main () {
int n[100], i = 0;
char x[100];
while(x[i] != '\n')
{
scanf(" %d %c", &n[i], &x[i]);
printf("%d %c ", n[i], x[i]);
i++;
}
return 0;
}
如何打破循环,并将所有这些值正确保存在阵列上?
答案 0 :(得分:0)
array(5) { ["username"]=> string(0) "" ["password1"]=> string(0) "" ["password2"]=> string(0) "" ["email"]=> string(0) "" ["submitted"]=> string(0) "" }
#include <stdio.h>
int main(void){
int n[100], i, j;
char x[100];
do {
for(i = 0; i < 100; ++i){
int ch;
while((ch = getchar()) != EOF && ch != '\n'){//check newline
if(ch == '-' || '0' <= ch && ch <= '9'){
ungetc(ch, stdin);//back to stream a character
break;
}
}
if(ch == EOF || ch == '\n')
break;
if(2 != scanf("%d %c", &n[i], &x[i])){
fprintf(stderr, "invalid format.\n");
i = 0;//End the outer do-while loop
break;
}
}
//print
for(j = 0; j < i; ++j){
printf("(%d, %c)", n[j], x[j]);
}
printf("\n");
} while(i != 0);//End with empty line
}
答案 1 :(得分:0)
scanf
and fscanf
have many problems所以最好避免它们。
处理输入的一般模式是创建一个大的输入缓冲区,然后将其处理成更小的块。
char line[4096];
fgets( line, sizeof(line), stdin );
由于line
被重用,所以可以使它足够大以容纳任何合理的输入。
现在您已经在内存中读取了一行,它是一个已知大小的字符串,可以根据需要进行处理。 sscanf
(字符串上的scanf)没有scanf
的大部分问题,但它也不适合移动字符串。一种方法是使用strtok
将字符串拆分为空格上的标记,并将它们交替处理为字母和数字。
const char sep[] = " \t\n";
bool expect_letter = false;
for(
char *token = strtok( line, sep );
token != NULL;
token = strtok( NULL, sep )
) {
if( expect_letter ) {
printf("Letter %s\n", token);
expect_letter = false;
}
else {
printf("Number %s\n", token);
expect_letter = true;
}
}
如果你想将它们存储在数组中,那么分配你希望足够的内存是不好的做法。您将不得不使用根据需要增长的数组。 C没有这些内置。你可以编写自己的,这是一个很好的练习,但很容易出错。对于制作use one from a library such as Glib。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <glib.h>
int main() {
// Read a single line of input into a buffer.
char line[4096];
fgets( line, sizeof(line), stdin );
// Create arrays to hold letters and numbers, these will grow as needed.
GArray *numbers = g_array_new( FALSE, TRUE, sizeof(int) );
GArray *letters = g_array_new( FALSE, TRUE, sizeof(char) );
// Split the string on whitespace into tokens.
const char sep[] = " \t\n";
gboolean expect_letter = FALSE;
for(
char *token = strtok( line, sep );
token != NULL;
token = strtok( NULL, sep )
) {
if( expect_letter ) {
// Need an error check to ensure that `token` is a single character.
g_array_append_val( letters, token[0] );
expect_letter = FALSE;
}
else {
// strtol is a better choice, it has error checking
int num = atoi(token);
g_array_append_val( numbers, num );
expect_letter = TRUE;
}
}
// Print the numbers and letters.
for( guint i = 0; i < letters->len; i++ ) {
printf(
"%d%c\n",
g_array_index( numbers, int, i ),
g_array_index( letters, char, i )
);
}
}
请注意,GLib提供了自己的布尔值,所以我切换到了它而不是stdbool来保持一致。
如评论中所述,这不包括检查令牌是否符合预期。也可以使用没有字母的数字,因此检查letters
和numbers
的大小是否相同会很好。或者你可以创建一个结构来保存字母/数字对,并有一个结构列表。