Thread: string array stuck:(

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    20

    string array stuck:(

    After a few hours looking to my code and thinking I realised that I was totally stuck and could not find any way to solve my problem in my mind. The problem is shortly;
    I wanna take a certain number of strings that the number will be defined by the user and store them in an array or I do not know exactly where... Its easy to take one or more strings but if the number will be given by the user thats a problem for me. Is there any way to store them in an array? I am really and totally stuck, searched in the forums and tutorials but did not see anything like that. Anyone please help me!

  2. #2
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    what you need is to dynamically allocate memory. Read this link,
    filker0 describes how to set up a 2-d array - you can read your
    strings into each row of this.
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    20

    thanks

    I really appreciate your fast answer. I already know how to set up a 2D array but did not know that I can store strings into each row of it. Thank you so much.

  4. #4
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    you can even use strcpy i think, to save yourself some time.
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  5. #5
    Registered User
    Join Date
    Dec 2003
    Posts
    167
    An example:

    Code:
     
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
    	int num_strings; 
    
    	// Declares a pointer to a char array of 80 chars
    
        char (*string_pointer)[80];  
     
    	printf("Enter the number of strings:\n"); 
        scanf("%d", &num_strings); 
    
    	// Allocate storage 80 chars for each string
        // and cast the pointer returned to a pointer 
        // to a 80 character string. 
        // Advancing the pointer moves to the next 
        // 80 characters 
    
        string_pointer = (char (*)[80])malloc(sizeof(*string_pointer) * num_strings); 
    
    	for( int i = 0; i < num_strings; i++)
        {
    		scanf("%s", &string_pointer[i]); 
        }
    
        for( int i = 0; i < num_strings; i++)
        {
    		printf("%s\n", string_pointer[i]); 
        }
    
    
        return 0;
    }
    silk.odyssey

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    20

    thanks to everyone

    I really really appreciate your work and help, I am embarassed to ask a question like this easy. It makes me feel I have a long way to come where you are, thanks again

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > string_pointer = (char (*)[80])malloc(sizeof(*string_pointer) * num_strings);
    I guess you haven't read the FAQ then?
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    So, why did you cast it?
    To hide your failure to include stdlib.h?
    To mask the fact that you used a C++ compiler to compile your code?
    Perhaps it is C++ code, with the way you declare i inside the for loop.

    Your scanf call is wrong as well - you don't need the &
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    20
    I did not have time to try the code above if it is working but the point is that helped me with my problem with their point of view. Also for anyone to know, my program was to be written in C not C++ and I dont know if malloc() function will work properly like in C++ in my program. I will try to find in a few hours.

  9. #9
    Registered User
    Join Date
    Dec 2003
    Posts
    167
    >I guess you haven't read the FAQ then?
    >http://faq.cprogramming.com/cgi-bin...8&id=1043284351

    Just read it thanks.

    >So, why did you cast it?
    >To hide your failure to include stdlib.h?

    Ah I casted because the compiler was complaining about the return type and the pointer type. I guess because I didn't include stdlib.h the compiler assumed that malloc returned int which had to be casted to the right type. I have checked the header and I see it returns void *. Now the cast is not necesary. Thanks.

    >To mask the fact that you used a C++ compiler to compile your code?
    >Perhaps it is C++ code, with the way you declare i inside the for loop.

    Actually I used pellesc which supports C99.

    Your scanf call is wrong as well - you don't need the &

    >LOL I almost never never use(d) scanf but I see it just wants a pointer. Thanks.
    silk.odyssey

  10. #10
    Registered User
    Join Date
    May 2006
    Posts
    20
    I have modified silk.odyssey's code a bit and finally I made the program work as I wanted. Before posting this thread, I worked for hours to compile this program without sizeof and malloc functions. But probably because of I was working with strings nomally allocated memory space was not enough for long strings.
    Here is my code below:
    Code:
    #include<stdio.h>
    #include <stdlib.h>
    
    
    
    
    
    main(){
           int ch,num=0,i,j,k=0;
           float av=0;
           char (*id)[100],(*name)[100],(*sname)[100],grade[100];
    
           
           printf("Menu:\n 1. Student registration (Student id, name, surname).\n 2. Course list (including student id, name, surname).\n"
           " 3. Final results entrance of each student.\n 4. Average of the final.\n 5. Exit\n");
           
           do{
           printf("enter your choice:");
           scanf("%d",&ch);
           switch(ch){
                      
                      case 1:
                      printf("how many students: \n");
                      scanf("%d",&num);
                      id = malloc(sizeof(*id) * num);
                      name = malloc(sizeof(*name) * num); 
                      sname = malloc(sizeof(*sname) * num);  
                      for(i=0;i<num;i++){
                                         printf("please enter student ID: ");
                                         scanf("%s",&id[i]); 
                                         printf("please enter student name: ");
                                         scanf("%s",&name[i]);
                                         printf("please enter student surname: ");
                                         scanf("%s",&sname[i]); 
                                         }                
                      break;
                      
                      
                      case 2:
                             printf("\n\n");
                             printf(" Course List:\n\n");
                             printf("student id\tname\tsurname\n");
                             for(i=0;i<(2*'\t'+14);i++){
                                                        printf("-");
                                                        }
                                                        printf("\n");
                             for(j=0;j<num;j++){
                                                printf("%10s\t%4s\t%7s\n",&id[j],&name[j],&sname[j]);
                                                }
                                                
                                        
                                        
                           break;
                      case 3:
                           for(j=0;j<num;j++){
                                                printf("%s:",&id[j]);
                                                scanf("%d",&grade[j]);
                                                }
                           
                           
                           
                           break;
                      case 4:
                            for(j=0;j<num;j++){
                                               av+=grade[j];
                                               }
                                               av=av/num;
                            printf("average of the final is: %.2f\n",av);
                           
                           
                           break;
                      case 5:
                           exit(0);
                           }
                           }while(ch!=5);
           getch();                    
    return 0;
    }
    Is there anyway to do the same work without using these functions. I am asking this because I saw that my knowledge was not also enough to do that. If you say no you can not, I will stop trying
    Finally if you noticed, I had to use & even in printf statements because of the structure of pointers that I used. When I change the pointer names for example: (*id) to *id, the program crashes. I am totally confused sorry
    Last edited by mass; 05-20-2006 at 05:39 PM.

  11. #11
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    There's a few things wrong with that code - these are the
    fisrt few I noticed - there's probably more but its late here and I'm
    off to bed in a minute:

    1) you never deallocate the memory you allocate with malloc -
    this is very bad practice, and silk.oddyssey is partly to blame
    since I assume that you learned from his code. You need to
    call free and pass it the pointer that stores malloc's return.
    serious
    2) main returns int - see my sig on why
    3) getch is a nonstandard function that is defined in conio.h
    which you haven't included - either include it or remove it since
    it serves no purpose at present
    4) This looks set to trash your data if the person decides that
    they want to enter information for than once (i.e. they select
    option 1 more than once) - this should really have been
    asked outside of a loop and at the start of your program -
    one allocation instead of possible multiple allocations which
    will destroy your original data. serious

    Code:
                      case 1:
                      printf("how many students: \n");
                      scanf("%d",&num);
                      id = malloc(sizeof(*id) * num);
                      name = malloc(sizeof(*name) * num); 
                      sname = malloc(sizeof(*sname) * num);  
                      for(i=0;i<num;i++){
    To answer your question, yes this could have been done using
    static memory allocation - its not specifically a size restraint
    that was causing your problem, but rather you most likely coded
    it incorrectly. sizeof isn't a function, i think its a language
    operation (keyword) - you should have no fear of it.

    finally, this program would be better designed if you had used
    a struct to store all the student's details - then dynamically
    allocated as many structs for as many students you had -
    would be simpler to manage.
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Finally if you noticed, I had to use & even in printf statements because of the structure of pointers that I used.
    Which basically means you got something else wrong as well.
    So rather than fix the original mistake, you make a mess of it somewhere else, where there is less error checking.
    Sooner or later, printf/scanf format abuse will catch up to you, and it can be hard to track down exactly what the problem is.

    Get a better compiler, or wind up the diagnostics if you're using gcc.
    This is what I get with your code.
    Code:
    $ gcc -W -Wall -ansi -pedantic -O2 foo.c
    foo.c: In function ‘main’:
    foo.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:32: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:34: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:47: warning: format ‘%10s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:47: warning: format ‘%4s’ expects type ‘char *’, but argument 3 has type ‘char (*)[99u]’
    foo.c:47: warning: format ‘%7s’ expects type ‘char *’, but argument 4 has type ‘char (*)[99u]’
    foo.c:53: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:54: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘char *’
    foo.c:6: warning: unused variable ‘k’
    foo.c:8: warning: ‘sname’ may be used uninitialized in this function
    foo.c:8: warning: ‘name’ may be used uninitialized in this function
    foo.c:8: warning: ‘id’ may be used uninitialized in this function
    Try this
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
      int ch, num = 0, i, j;
      float av = 0;
      char (*id)[100] = NULL, (*name)[100] = NULL, (*sname)[100] = NULL;
      /*int  grade[100]; */
      /*!! I think you wanted num students of this as well */
      int *grade = NULL;
    
      printf("Menu:\n"
             "1. Student registration (Student id, name, surname).\n"
             "2. Course list (including student id, name, surname).\n"
             "3. Final results entrance of each student.\n"
             "4. Average of the final.\n"
             "5. Exit\n");
    
      do {
        printf("enter your choice:");
        scanf("%d", &ch);
    
        switch (ch) {
    
        case 1:
          printf("how many students: \n");
          scanf("%d", &num);
          id = malloc(sizeof(*id) * num);
          name = malloc(sizeof(*name) * num);
          sname = malloc(sizeof(*sname) * num);
          grade = malloc(sizeof(*grade) * num);
          for (i = 0; i < num; i++) {
            printf("please enter student ID: ");
            scanf("%s", id[i]);
            printf("please enter student name: ");
            scanf("%s", name[i]);
            printf("please enter student surname: ");
            scanf("%s", sname[i]);
          }
          break;
    
        case 2:
          printf("\n\n");
          printf(" Course List:\n\n");
          printf("student id\tname\tsurname\n");
          for (i = 0; i < (2 * '\t' + 14); i++) {
            printf("-");
          }
          printf("\n");
          for (j = 0; j < num; j++) {
            printf("%10s\t%4s\t%7s\n", id[j], name[j], sname[j]);
          }
          break;
    
        case 3:
          for (j = 0; j < num; j++) {
            printf("%s:", id[j]);
            scanf("%d", &grade[j]);
          }
          break;
    
        case 4:
          for (j = 0; j < num; j++) {
            av += grade[j];
          }
          av = av / num;
          printf("average of the final is: %.2f\n", av);
          break;
    
        case 5:
          /*exit(0); */
          break;
        }
      } while (ch != 5);
    
      free(id);
      free(name);
      free(sname);
      free(grade);
      getchar();
      return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    May 2006
    Posts
    20
    Quote Originally Posted by Richie T
    There's a few things wrong with that code - these are the
    fisrt few I noticed - there's probably more but its late here and I'm
    off to bed in a minute:

    1) you never deallocate the memory you allocate with malloc -
    this is very bad practice, and silk.oddyssey is partly to blame
    since I assume that you learned from his code. You need to
    call free and pass it the pointer that stores malloc's return.
    serious
    2) main returns int - see my sig on why
    3) getch is a nonstandard function that is defined in conio.h
    which you haven't included - either include it or remove it since
    it serves no purpose at present
    4) This looks set to trash your data if the person decides that
    they want to enter information for than once (i.e. they select
    option 1 more than once) - this should really have been
    asked outside of a loop and at the start of your program -
    one allocation instead of possible multiple allocations which
    will destroy your original data. serious
    1)In the last reply that Salem posted, he showed me how to deallocate and I will do that from now on, thanks.
    2)I read the FAQ and changed the prototype as "int main(void)", thanks.
    3)As you said getch() has no use there, only to make the program wait to see the output before it closes itself. I could use a "scanf" there too.
    4)I really do not need to run the first case more than once, thats why I did not ask the user if he or she either wants to, thanks for the useful info.

    Quote Originally Posted by Salem
    > Finally if you noticed, I had to use & even in printf statements because of the structure of pointers that I used.
    Which basically means you got something else wrong as well.
    So rather than fix the original mistake, you make a mess of it somewhere else, where there is less error checking.
    Sooner or later, printf/scanf format abuse will catch up to you, and it can be hard to track down exactly what the problem is.

    Get a better compiler, or wind up the diagnostics if you're using gcc.
    This is what I get with your code.
    Code:
    $ gcc -W -Wall -ansi -pedantic -O2 foo.c
    foo.c: In function ‘main’:
    foo.c:30: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:32: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:34: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:47: warning: format ‘%10s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:47: warning: format ‘%4s’ expects type ‘char *’, but argument 3 has type ‘char (*)[99u]’
    foo.c:47: warning: format ‘%7s’ expects type ‘char *’, but argument 4 has type ‘char (*)[99u]’
    foo.c:53: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[99u]’
    foo.c:54: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘char *’
    foo.c:6: warning: unused variable ‘k’
    foo.c:8: warning: ‘sname’ may be used uninitialized in this function
    foo.c:8: warning: ‘name’ may be used uninitialized in this function
    foo.c:8: warning: ‘id’ may be used uninitialized in this function
    Currently I am using devcpp-4.9.9.2 and I got no error messages with my previous code. But definitely youre right, equaling the pointer arrays to NULL seems to fixed the problem. Also I did not notice before but I declared grade array as char, which was supposed to take integers.
    Thank you both for giving time to my problem and helping. I learned much from you.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Currently I am using devcpp-4.9.9.2
    Which uses gcc "under the hood", so you should be able to configure your own set of options for diagnosing potential problems.

    > equaling the pointer arrays to NULL seems to fixed the problem.
    It silences the compiler, but you would still need to make sure the user chose option 1 first.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Registered User
    Join Date
    May 2006
    Posts
    20
    after your suggestions and my failure with the malloc() function, I have modified my code again and here is the last version of it. I am posting this code because even my compiler did not encountered any errors some say that when the code is compiled with visual c there appears lots of errors. I need your suggestion and I want to do the things right. Thanks again.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    int choice=0,num=0;
    int k=0,l=0;
    float res=0;
    
    int main(void){
        
    
    printf("\n 1. Student registration.\n"
    " 2. List of course.\n"
    " 3. Enter final results.\n"
    " 4. Show average of final results.\n"
    " 5. Exit\n");
    printf("number of students: \n");
    scanf("%d",&num);
    char no[num][50],name[num][50],sur[num][50];
    int a1[num];
    while(choice!=5){
    printf("your choice:");
    scanf("%d",&choice);
    switch(choice){
    
    case 1:
             while(k<num){
                                                   
                          printf("ID: ");
                          scanf("%s",&no[k][0]);
                          printf("Name: ");
                          scanf("%s",&name[k][0]);
                          printf("Surname: ");
                          scanf("%s",&sur[k][0]);
                          k++;
                          }
    
    break;
    case 2:
                                   printf("\n");
                                   printf("ID\tName\tSurname\n");
                          do{
                                                for(k=0;no[l][k]!='\0';k++){
                                                                           printf("%c",no[l][k]);
                                                                           }
                                                                           printf("\t");
                                                for(k=0;name[l][k]!='\0';k++){
                                                                           printf("%c",name[l][k]);
                                                                           }
                                                                           printf("\t");
                                                for(k=0;sur[l][k]!='\0';k++){
                                                                           printf("%c",sur[l][k]);
                                                                           }
                                                                           printf("\n");
                                                                           l++;
                                                                           }while(l<num);
                          break;
    case 3:
                                   for(l=0;l<num;l++){
                                                         printf("%s:",name[l]);
                                                         scanf("%d",&a1[l]);
                                                         }
                                                         
                                   
                                   break;
    case 4:
                                            for(k=0;k<num;k++){
                                            res=res+a1[k];
                                            }
                                            res=res/(float)num;
                                            printf("average : %.2f\n",res);
                          break;
    case 5:
                          exit(1);
                          }     
    }
                                            
                         
    return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 03:58 PM
  2. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM
  3. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  4. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM