scanf()的双重用法取决于呼叫顺序

时间:2017-03-19 21:38:27

标签: c input scanf ternary-search

我在C中编写了一个程序,它将一个值和一个有序的整数数组作为输入,并执行三元搜索以找到数组内的值(如果存在)。

我已经看到了在Stackoverflow中使用scanf和相关主题的所有可能问题。

我注意到如果我以相反的顺序调用2个scanf函数会有区别。

如果我使用下面的代码。首先读取值,然后从用户那里读取数组,程序和scanf按预期运行。

printf("Enter the value to be searched in the Array: ");
int k;
scanf("  %d", &k);

printf("Type elements of A(sorted) separated by spaces (type 'end' to stop): ");

i = 0;  
while(scanf("%d", &A[i]) == 1) {
    i++;
}//while

虽然如果我以相反的顺序使用scanf输入,第二个scanf永远不会停止以获取用户输入并读取缓冲区中剩余的值。

printf("Type elements of A(sorted) separated by spaces (type 'end' to stop): ");

i = 0;  
while(scanf("%d", &A[i]) == 1) {
    i++;
}//while

printf("Enter the value to be searched in the Array: ");
int k;
scanf("  %d", &k);

我无法理解通话顺序的区别。 我已经尝试过其他线程中提到的解决方案但没有工作。

正如这里的引用是整个代码(按预期工作):

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


int ternarySearch(int A[], int l, int r, int k){
int i;
int first,second;

if(l>r){
    return -1;
}

i= (r - l)/3;

if(i==0){
    i++;
}

first = i+l-1;
second = i*2+l-1;

if(A[first]==k){
    return first;
}
else if(A[first]>k){
    ternarySearch(A, l, first-1, k);
}
else
 {
    if(A[second]==k)
      return second;
    else
    if(A[second]>k)
       ternarySearch(A, first+1,second-1, k);
    else
       ternarySearch(A, second+1,r, k);
 }
}


int main(){
const int maxarraylen = 1000;
int i;
int n;
int A[maxarraylen];
char string[250];

printf("Enter the value to be searched in the Array: ");
int k;
scanf("  %d", &k);

printf("Type elements of A(sorted) separated by spaces (type 'end' to stop): ");

i = 0;  
while(scanf("%d", &A[i]) == 1) {
    i++;
}//while
n=i-1;


//We assume the array is sorted otherwise we can use any sorting algorithm e.g. code from task1

scanf("  %d", &k);






int result;
result=ternarySearch(A, 0, n, k);

if(result==-1){
    printf("The value was not found in the Array.\n");
}
else{
    printf("The value was found in position no. %d.\n", result);
}

return 0;
}

1 个答案:

答案 0 :(得分:1)

你的问题是你没有跨过&#39;您的end输入。

我们可以通过使用以下程序进行实验来看到这一点:

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

void main(void) {
    FILE *f;
    long f_pos;
    int ret;
    int i;
    int data[5];
    int data_last;
    int search;

    f = fopen("./input.txt", "r");
    if (f == NULL) {
        perror("fopen()");
        return;
    }

    /* read in the values for the array */
    data_last = -1;
    for (i = 0; i < 5; i++) {
        ret = fscanf(f, "%d", &(data[i]));
        printf("fscanf(data[%d]): ret: %d\n", i, ret);
        f_pos = ftell(f);
        printf("ftell(): %ld\n", f_pos);
        if (ret != 1) {
            break;
        }
        data_last = i;
    }

    /* check that we read in at least one value */
    if (data_last == -1) {
        printf("no input data!\n");
        return;
    }

    /* insert 'fix' here */

    /* pre-load the 'search' with known garbage */
    search = 987;

    /* now read in the search value */
    ret = fscanf(f, "%d", &search);
    printf("fscanf(search): ret: %d\n", ret);
    f_pos = ftell(f);
    printf("ftell(): %ld\n", f_pos);

    /* print out our info */
    for (i = 0; i <= data_last; i++) {
        printf("data[%d]: %d\n", i, data[i]);
    }
    printf("search for: %d\n", search);

    return;
}

使用input.txt中的以下数据:

123
456
end
456

输出如下:

fscanf(data[0]): ret: 1
ftell(): 3
fscanf(data[1]): ret: 1
ftell(): 7
fscanf(data[2]): ret: 0
ftell(): 8
fscanf(search): ret: 0
ftell(): 8
data[0]: 123
data[1]: 456
search for: 987

ftell()告诉我们文件的光标在哪里,在这种情况下我们可以看到它位于字节8 ...输入行e的{​​{1}} }。

它没有超越它,因此下次尝试读取数字(end)也会失败!

检查返回值也是一个好主意!我们可以看到%d调用未能读取数字!

解决方法是在我们检查收到数组值后立即插入此代码段:

fscanf(&search)