scanf第二次没有读取输入

时间:2016-01-28 02:45:42

标签: c io scanf

我试图从标准输入中读取字符和行,但我遇到了麻烦。

这是我试图读入变量的输入:

6 4
engine
brakes
tires
ashtray
vinyl roof
trip computer
Chevrolet
20000.00 3
engine
tires
brakes
Cadillac
70000.00 4
ashtray
vinyl roof
trip computer
engine
Hyundai
10000.00 3
engine
tires
ashtray
Lada
6000.00 1
tires
0 0

第一行是两个数字,表示将列出多少部分,然后有多少公司会尝试匹配这些部分。

向下六行是试图匹配零件要求的公司的名称,之后的下一行是两个数字:汽车将花费多少,以及制造商可以满足多少零件要求。

然后,列出制造商可以放入汽车的零件。

然后,另一家制造商,他们的汽车成本,他们可以满足的零件,零件清单等。

最后,我打印出谁赢了中标。

这是我用来执行此操作的代码:

#define MAX_LEN 80

int main(){
    int rfpNum = 0;
    int n, p, reqMet, numMet, nCopy, numActualMet;
    float maxCompliance=-1, lowestBid=-1, tmpCompliance;
  float bid;
    char req[MAX_LEN], bidder[MAX_LEN];
    char winner[MAX_LEN];
    char **reqs;
    char *pos;

    while (scanf("%d %d *[^\n]", &n, &p), (n && p)){
        reqs = new char*[n];
        nCopy = n;

    maxCompliance = -1;

        while (nCopy--){
            fgets(req, MAX_LEN, stdin);
            if ((pos=strchr(req, '\n')) != NULL)
                *pos = '\0';
            reqs[nCopy] = new char[MAX_LEN];
            sprintf(reqs[nCopy], "%s", req);
        }

        while (p--){
            fgets(bidder, MAX_LEN, stdin);
            if ((pos=strchr(bidder, '\n')) != NULL)
                *pos = '\0';

            numActualMet = 0;
            scanf("%f %d *[^\n]", &bid, &numMet);

            while (numMet--){
                fgets(req, MAX_LEN, stdin);
                if ((pos=strchr(req, '\n')) != NULL)
                    *pos = '\0';
                for (int i=0; i<n; i++){
                    if (strcmp(req, reqs[i]) == 0) numActualMet++;
                }
            }
            tmpCompliance = (float) numActualMet/n;

            if (tmpCompliance > maxCompliance){
                maxCompliance = tmpCompliance;
                strncpy(winner, bidder, MAX_LEN);
        lowestBid = bid;
            }
            else if ((maxCompliance == tmpCompliance) && (lowestBid == -1 || bid < lowestBid)) {
                lowestBid = bid;
                strncpy(winner, bidder, MAX_LEN);
            }
        }

        rfpNum++;
        if (rfpNum != 1)
            printf("\n");

        printf("RFP #%d\n", rfpNum);
        printf("%s\n", winner);

    }
    return 0;
}

问题是,我必须在退出前输入0 0两次。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

  

问题是,我必须在退出前输入0 0两次。有什么想法吗?

该行

while (scanf("%d %d *[^\n]", &n, &p), (n && p)){

不仅要求两个整数读入np,还要等待非空格字符与格式的*[^\n]部分匹配。如果您输入任何字符,而不只是0 0,程序将停止。我可以通过输入abc来终止它。

更好的方法是使用fgets()后跟sscanf

char buffer[100]; // Make it large enough
while ( fgets(buffer, 100, stdin) != NULL )
{
   int n = sscanf(buffer, "%d %d", &n, &p);
   if ( n != 2 )
   {
      // Deal with error.
   }

   if ( n == 0 && p == 0 )
   {
      break;
   }

  // Rest of the loop

}

作为一项政策,请尽量避免混合使用fgetsfscanf。当它们一起使用时,它们充满了问题。