2017-03-18 41 views
2

我试图将字符串S作为输入。这里字符串S可以包含多个整数值,后跟一个字母表。该程序必须根据先前的整数值扩展字母表。如何从字符串中读取多个数字号码

考虑输入:4a5h 的量,输出:aaaahhhhh,即4倍a倍和5倍h

同样对于输入:10a2b 输出:aaaaaaaaaabb,即10倍a和2倍b

这是我的代码:

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

int main() { 
    char s[1000], alp[1000]; 
    int num[1000]; 
    int n = 0; 
    int i, j, k, m; 
    k = 0; 
    scanf("%[^\n]s", s);//Reads string until newline character is encountered 
    for (i = 0; i < strlen(s); i++) { 
     if (isalpha(s[i])) { 
      alp[n] = s[i]; // alp[] stores the alphabets 
      n += 1; 
     } else { 
      num[k] = s[i] - '0';// num[] stores the numbers 
      k += 1; 
     } 
    } 
    for (i = 0; i < k; i++) { 
     for (m = 0; m < num[i]; m++) 
      printf("%c", alp[i]); 
    } 
    return 0; 
} 

但是,通过此代码,我无法读取2或3或N位数字。因此,如果输入是100q1z那么alp[]阵列很好,但num[]阵列不包含1001,因为它的元素代替10是它的元素。

如何纠正这种代码?

+0

1)'k'应'0'作为初始值。 – BLUEPIXY

+0

感谢那@BLUEPIXY –

回答

2

你应该修改循环处理尽可能多的数字存在先后INT字符串:

#include <ctype.h> 
#include <stdio.h> 

int main(void) { 
    char s[1000], alp[1000]; 
    int num[1000]; 
    int i, k = 0, m, n; 

    //Read string until newline character is encountered 
    if (scanf("%999[^\n]", s) == 1) { 
     for (i = 0; s[i]; i++) { 
      n = 1; 
      if (isdigit((unsigned char)s[i])) { 
       for (n = s[i++] - '0'; isdigit((unsigned char)s[i]); i++) { 
        n = n * 10 + s[i] - '0'; 
       } 
      } 
      if (isalpha((unsigned char)s[i])) { 
       alp[k] = s[i]; // store the letter 
       num[k] = n; // store the number 
       k += 1; 
      } 
     } 
     for (i = 0; i < k; i++) { 
      for (m = 0; m < num[i]; m++) 
       putchar(alp[i]); 
     } 
    } 
    putchar('\n'); 
    return 0; 
} 

注:

  • 包括<ctype.h>使用isalpha()
  • 通过使字符的最大数目保护scanf目标数组并检查返回值。
  • 用于将一个非空行的格式仅仅是%[^\n],后s不正确。请注意,与fgets()不同,如果该行为空,则此scanf()格式将失败。
  • 您应该始终测试scanf()的返回值。
  • char参数强制转换为isalpha()isdigit()作为(unsigned char)以避免未定义的行为,如果char已签名并且具有负值。
  • 使用putchar(c)输出单个字符,而不是printf("%c", c);
+0

这是完全正确的。我猜在内部if循环中有一个错字。感谢@chqrlie –

+0

@ Lingesh.K:是的!答案已更正。 – chqrlie

0

与代码的问题是,当你在字符串中遇到的一个数字,你正在考虑它作为一个数并将其存储在NUM阵列。

这是好的,如果你有数组中唯一单个数字

对于多位数字做这个 -
阅读的数字,直到你利用所获得的数字找到一个字母,形成一个数字,然后将其保存为num阵列的字符串。

我离开代码给你。

1

其他-bolock的部分必须循环。

这样

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> //need this for isalpha and isdigit 

int main(void){ 
    char s[1000], alp[1000]; 
    int num[1000]; 
    int m = 0, n = 0; 
    int i, j; 
    unsigned char ch;//convert char to unsigned char before use isalpha and isdigit 

    scanf("%999[^\n]", s);//remove s after [^\n] and Add limit 
    for(i = 0; ch = s[i]; i++){//replace strlen each loop 
     if(isalpha(ch)){ 
      alp[n++] = s[i]; 
     } else if(isdigit(ch)){ 
      num[m] = 0; 
      while(isdigit(ch = s[i])){ 
       num[m] = num[m] * 10 + s[i] - '0'; 
       ++i; 
      } 
      ++m; 
      --i;//for ++i of for-loop 
     } else {//Insufficient as validation 
      printf("include invalid character (%c).\n", ch); 
      return -1; 
     } 
    } 
    for(i = 0; i < m; i++){ 
     for(j = 0; j < num[i]; j++) 
      printf("%c", alp[i]); 
    } 
    puts(""); 

    return 0; 
} 
+0

这将解析'a5d4'并生成'aaaaadddd'并在'a'和'5ab'等处调用未定义的行为。 – chqrlie

+0

@chqrlie yes,验证不足。 – BLUEPIXY

+1

另一方面,规范是不够的;-) – chqrlie