1

I am attempting to create a program that will allow a user to search for a name in a file. The program does this successfully, but then it occurred to me that not everyone will type in the name as it is capitalized in the file. That is, someone may search for "sarah," but as the name is listed as "Sarah" in the file the name will not be found. To get around this I have attempted to convert both strings into upper case at the time of comparison. I am very, very new to teaching myself C, so I am not certain if I am even heading in the right direction. At this point I cannot even get the program to compile as I am getting two errors that say "array initializer must be an initializer list or string literal." I'm assuming that to mean that my syntax is not only invalid but completely in the wrong direction. What would be the best way to approach my goal?

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

     int main(void)
     {
        FILE *inFile;
        inFile = fopen("workroster.txt", "r");
        char rank[4], gname[20], bname[20], name[20];

        printf("Enter a name: __");
        scanf("%s", name);
        int found = 0;
        while(fscanf(inFile, "%s %s %s", rank, bname, gname)== 3)
        {   char uppername[40] = toupper(name[15]);
            char upperbname[40] = toupper(bname[15]);
            if(strcmp(uppberbname,uppername) == 0)
            {
                printf("%s is number %s on the roster\n", name, rank);
                found = 1;
            }
        }

        if ( !found )
            printf("%s is not on the roster\n", name);

        return 0;

      }
eruiggy
  • 25
  • 5
  • 6
    A good place to start would be learning how the api's you're calling *actually function*. `toupper`, for example, returns a single `char`, and is thus unsuitable to initialize `char` *array*. Btw, if you don't mind hitching your wagon to the posix tractor, [`strcasecmp`](http://pubs.opengroup.org/onlinepubs/009695399/functions/strcasecmp.html) will probably make this task much easier (or [`_stricmp`](https://msdn.microsoft.com/en-us/library/k59z8dwe.aspx) in Windoze). – WhozCraig Apr 19 '16 at 03:59
  • Make certain you validate and limit all input. e.g. `if (scanf ("%19[^\n]%*c", name) != 1) { fprintf (stderr, "error: invalid input.\n"); return 1;}` not just the input you read from the file. What if the user enters `someverylongstring__%%with+malicious+commands%%`? – David C. Rankin Apr 19 '16 at 05:03

4 Answers4

1

This two lines are wrong:

char uppername[40] = toupper(name[15]);
char upperbname[40] = toupper(bname[15]);

int toupper(int c); takes an int and returns an int

Because in C string is just an array of chars with a null terminator, so what you can do is to convert each character of the string to uppercase:

for (size_t I = 0; I < strlen(name); I++) {
    uppername[I] = toupper(name[I]);
}
uppername[I] = '\0';

Regarding compare, you can use strcasecmp as suggested, which is Posix. If you want to just use function in the C stdlib, convert the string as above, and then use strcmp.

fluter
  • 13,238
  • 8
  • 62
  • 100
1

toupper() works on a single character, not on a string.

No need to convert the input strings. Simple call a string case-insensitive compare.

As C does not have a standard one, it is easy enough to create your own.

int mystricmp(const char *s1, const char *s2) {
  // toupper works with unsigned char values.
  // It has trouble (UB) with char, when char is signed.
  const unsigned char *p1 = (const unsigned char *) s1;   
  const unsigned char *p2 = (const unsigned char *) s2;   

  while (toupper(*p1) == toupper(*p2) && *p1) {
    p1++;
    p2++;
  }

  int ch1 = toupper(*p1);
  int ch2 = toupper(*p1);
  return (ch1 > ch2) - (ch1 < ch2);
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

use the following function, which is included in strings.h

int strcasecmp(const char *s1, const char *s2);

in your case change if statement

if(strcmp(uppberbname,uppername) == 0)

to

if(strcasecmp(bname,name) == 0)

and delete

char uppername[40] = toupper(name[15]);
char upperbname[40] = toupper(bname[15]);
shafeeq
  • 1,499
  • 1
  • 14
  • 30
0

Because the function toupper is for converting a character from small to capital, you cannot use it for a string case conversion. But you can string using the same function in this way:

  while(name[i])
  {
     uppername[i]=toupper(name[i]);
     i++;
  }
  while(bname[j])
  {
     upperbname[j]=toupper(bname[j]);
     j++;
  }

These statements do our string case conversion. The whole Program:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void) {
  FILE *inFile;
  inFile = fopen("workroster.txt", "r");
  char rank[4], gname[20], bname[20], name[20], uppername[40], upperbname[40];
  printf("Enter a name: __");
  scanf("%s", name);
  int found = 0, i = 0, j = 0;

  while (fscanf(inFile, "%s %s %s", rank, bname, gname) == 3) {
    while (name[i]) {
      uppername[i] = toupper(name[i]);
      i++;
    }
    while (bname[j]) {
      upperbname[j] = toupper(bname[j]);
      j++;
    }

    //char uppername[40] = toupper(name[15]);
    //char upperbname[40] = toupper(bname[15]);
    if (strcmp(uppername, upperbname) == 0) {
      printf("%s is number %s on the roster\n", name, rank);
      found = 1;
    }
  }

  if (!found) printf("%s is not on the roster\n", name);
  return 0;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256