1

I created a program that accepts strings and stores them in a two-dimensional array, It also has a function that searches for a string(inputted by the user) in the array. But whenever I run the program, it stops working when it reaches the searching part. Can anyone point out my error?

Here's my code

#include <stdio.h>
#include <string.h>
#define maxname 40
#define maxlength 70

int acceptSize()
{
    int sizeOf;
        printf("How many students?");
        scanf("%d",&sizeOf);    
    return sizeOf;
}

void acceptNames(char names[maxname][maxlength],int size)
{
    int ctr;
    for(ctr=0; ctr<size; ctr++)
    {
        printf("Student %d:", ctr+1);
        scanf("%s",&names[ctr]);
    }

}

int searchName(char names[maxname][maxlength], char sname[maxname]){
    int ctr2;
        for(ctr2=0; ctr2<maxname; ctr2++)
        {
            if(strcmp(names[ctr2], sname[maxname])==0)
            {
                return ctr2;
            }
        }
    return -1;
}

int main(){
    int ctr,size, choice, result;
    char names[maxname][maxlength], sname[maxlength];

    size=acceptSize();
    acceptNames(names,size);
    printf("Enter name to be searched: ");
    scanf("%s", &sname[maxlength]);
    result=searchName(names, sname);
    if(result == -1)
        printf("Match is not found.");
    else
        printf("Match is found!");
}
  • 2
    Use a debugger. But what do you expect `scanf("%s", &sname[maxlength]);` should do? – cadaniluk Aug 08 '16 at 20:35
  • Checking the return value from `scanf` family is *essential*, even if there is no monkey on the typewriter, we all enter mistakes. It returns the number of items successfully read. And you give no clue as to expected input, or output. For example, if I enter my name as `Weather Vane` your program will not work, for reasons divulged by the man page for `scanf` with the `%s` format. – Weather Vane Aug 08 '16 at 20:42
  • it accepts the string that will be searched in the array. @Downvoter – Choco Fernandez Aug 08 '16 at 20:45
  • it might accept *one word* of the string that will be searched in the array. – Weather Vane Aug 08 '16 at 20:46
  • `&sname[maxlength]` is the address of the end of the string, so you cause a buffer overflow. The start of the string would be `&sname[0]` – M.M Aug 08 '16 at 23:09
  • you could even do rc = scanf("%s", sname) – bruceg Aug 08 '16 at 23:33

1 Answers1

3
char sname[maxname] // in int searchName()

should've been

char sname[]; // See comment#1 by weather-vane

Also

if(strcmp(names[ctr2], sname[maxname])==0)

should've been

if(strcmp(names[ctr2], sname)==0) // sname[maxname] is not a string, sname is !!

finally

scanf("%s", &sname[maxlength]);

shoud've been

scanf("%s", sname); // reading a string is a case where you could omit &

And a suggestion : Use [ fgets ] instead of scanf

use

sjsam
  • 21,411
  • 5
  • 55
  • 102
  • 1
    +1 but your first point, a function could not care what length of array you tell it, of one dimension, since C has no array bounds checking. It's only important for multi-dimensional arrays, so the compiler can figure out the indexing. – Weather Vane Aug 08 '16 at 20:53
  • Thank you so much for your input! I really appreciate it. – Choco Fernandez Aug 08 '16 at 21:00
  • `And a suggestion : Use [ fgets ] instead of scanf` Why is That? `scanf` is perfectly safe when used right. The problem with `scanf` is that is used wrong. Please explain – Michi Aug 08 '16 at 21:04
  • I have corrected my program and it's working fine now, except for the part where the string being searched is not found in the array—the program stops working. @sjsam – Choco Fernandez Aug 08 '16 at 21:04
  • 2
    @Michi Using fgets will allow you to deal with invalid input, e.g. monkeys at the keyboard. You could even search for every word that the user inputs. It's a lot more flexible and stable without the bugs that scanf will cause. irover- Great link. – mgarey Aug 08 '16 at 21:07
  • @iRove I don't need to see that. `scanf` is all most always used wrong. – Michi Aug 08 '16 at 21:07
  • @mgarey Please show me a [demo](http://www.ideone.com) with `fgets` where `scanf` doesn't work. – Michi Aug 08 '16 at 21:09
  • Never mind my previous comment, I fixed it by putting an else within the for loop of searchName instead of just returning -1. – Choco Fernandez Aug 08 '16 at 21:11
  • @Michi Say you were trying to get a number from the user with `scanf`. How do you deal with buffer overflows like in [this case](http://ideone.com/1S62AD)? – iRove Aug 08 '16 at 21:16
  • @iRove Really? You should already know this. Any way this is a bad example. How does `fgets` even works here? :)) – Michi Aug 08 '16 at 21:18
  • @Michi I am still learning. This is why I am interested in your point. So, how do you avoid something like this? – iRove Aug 08 '16 at 21:19
  • @iRove No problem. All of us we learn every day something new. Nothing is wrong with `scanf`, I repeat...is just **WRONG USED**. – Michi Aug 08 '16 at 21:20
  • @Michi Ok...I'm sure your point is fair ;-). Could you enlighten me as how you would use `scanf` correctly in my demo? – iRove Aug 08 '16 at 21:22
  • @iRove You don't catch the Point here. I have to ask you again, how does `fgets` solve this if we have `int a` ? How can/does this be related to `fgets` ? – Michi Aug 08 '16 at 21:27
  • @Michi I typically would use `fgets` first, and then `sscanf` it into the format I want. I might solve the problem I showed before by doing something like [this](http://ideone.com/KLxuQS). Sorry it took me so long to respond - was trying to get something else done :-) – iRove Aug 08 '16 at 22:08
  • @Michi Can you get `scanf` to truncate your input when getting a number with _"%d"_? Maybe you can, I am just unaware of how you would do this. It is, I think, one of the main advantages of using `fgets`. – iRove Aug 08 '16 at 22:39
  • 1
    @Michi : *fgets* was suggested for the reasons mentioned in [\[ this \]](http://stackoverflow.com/a/3302594/1620779) answer. – sjsam Aug 09 '16 at 01:47
  • @WeatherVane : Good note, Thankyou and corrected. – sjsam Aug 09 '16 at 02:52