【问题标题】:Check a format of a line read in stdin to be number^number检查在标准输入中读取的行格式为 number^number
【发布时间】:2014-11-03 23:51:33
【问题描述】:

我想用 c 语言编写一个程序,在 while 循环中使用 getline 从标准输入读取一行。 如果该行字符的格式为“number^number”,那么它会计算结果并打印出来。例如,如果用户键入 33^2,那么它将打印 1089。所以我想知道如何检查格式是否正确,否则它会向stderr 返回错误消息,并且用户必须输入另一行。我知道我必须使用strtol 将char 转换为long。

另外,我想知道如何使用getline 来阅读stdin。我只知道怎么用fgets

这是我尝试过但不起作用的代码部分:

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

long power(long, long);

long power(long x, long y) {

  if (y == 0) {
    return 1;
    }
    else {
    return x*power(x, y-1);
    }
}

int main(void) {

char *line =(char *) malloc(100*sizeof(char));
char *number1=(char *) malloc(100*sizeof(char));
char *number2=(char *) malloc(100*sizeof(char));
long x;
long y;

printf("User please enter The following format number1^number2\n");
int index;
int length;
while(fgets(line, sizeof line, stdin)!= NULL) { // I want to use getline instead
length=strlen(line);
index = strchr(line,"^")-line; //find the index of "^" in the line

if ((index<0) || (index!=0) || (index!= length-1)) {
  fprintf(stderr,"The format is wrong it should be number1^number2\n");
}
else{
for (int i=0; i<index; i++) {
number1[i]=line[i];
}
for (int j=index+1; j<length; j++) {
number1[j]=line[j];
}
x=strtol(number1);
y=strtol(number2);
printf("%ld^%ld = %ld\n",x,y,power(x,y));
}

}



  return EXIT_SUCCESS;
}

我还想知道如何在while 的每次迭代中释放我为所有动态数组分配的内存。

在此先感谢

【问题讨论】:

  • while(fgets(line, sizeof line, stdin)!= NULL) { sizeof 的工作方式与您想象的不同。
  • 1) strchr(line,"^") --> strchr(line, '^') 2) if ((index&lt;0) || (index!=0) || (index!= length-1)) { 条件不好。

标签: c string memory-management malloc getline


【解决方案1】:
#include <stdio.h>
#include <stdlib.h>

//ssize_t getline(char **linep, size_t *n, FILE *fp);

unsigned long power(unsigned long base, unsigned long exp) {
    unsigned long result = 1;
    while(exp > 0){
        if(exp & 1)
            result = result * base;
        base = base * base;
        exp >>=1;
    }
    return result;//Overflow is not considered
}

int main(void) {
    char *line = NULL;
    size_t size = 0;
    unsigned long x;
    unsigned long y;

    printf("User please enter The following format number1^number2\n");
    while(getline(&line, &size, stdin)!=-1){
        if(2!=sscanf(line, "%lu^%lu", &x, &y)){
            fprintf(stderr,"The format is wrong it should be number1^number2\n");
            continue;
        }
        printf("%lu^%lu = %lu\n", x, y, power(x,y));
    }
    free(line);
    return EXIT_SUCCESS;
}

【讨论】:

  • 非常感谢您的回答。它完美地工作!我只是有一个关于释放内存的问题。你能告诉我我们何时使用命令free 以及使用malloc 后我们如何使用它。有没有办法在 while 循环内的每次迭代中释放内存?
  • @user2987 getline 不只是在每次调用时保护新内存。所以不需要循环释放。
【解决方案2】:

你可以用sscanf()解析你的字符串

int res = sscanf(line, "%d^%d", &n1, &n2);

在此之后,您可以检查 res var。如果 res = 2,则解析正确数量的参数。然后你可以调用你的函数来计算 n1^n2。

编辑:你不能转换 mallocs。

对于getline:

char *line = null
int n = 0; /* If n = 0 getline will automaticely allocate the right memory */
getline(&line, &n, stdin)

别忘了free()你的线路

【讨论】:

  • getline 的第二个参数类型是size_t*
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多