-2

I got a question.

I want to have a FOR loop that prints back text many strings. Lets say I type my forename and last name. And a FOR loop produce the strings.

#include <stdio.h>
int main(){

   char str1 [12];
   char str2 [12];
   char wordarray [2]={str1,str2}; // error here
   int i;

   printf ("Type your forname : ");
   scanf ("%s",&str1);
   printf ("\nType your last name : ");
   scanf ("%s",&str2);

   printf ("\n\nYour name is : ");
   printf ("%s\t%s",str1,str2);
   printf ("\n");

   for (i=0;i<3;i++){
      printf ("%s",wordarray [i]); // Error here . 
   } // end FOR

   return 0;
} // end MAIN
  • what does this:"prints back text many strings" mean? – Akhter Al Amin Jan 02 '17 at 03:27
  • What error messages are you getting? – Schomes Jan 02 '17 at 03:30
  • First, you should probably fix your for loop as there are only 2 elements in `wordarray`, not 3. – Michael Albers Jan 02 '17 at 03:30
  • many text string would mean. my name and my last name. in this case . In the FOR loop I can do it with numbers and single letters. but not with a string – Radar Blue Jan 02 '17 at 03:33
  • 1
    Step 1: fix error/warnig casued by `char wordarray [2]={str1,str2};`. Use `char *wordarray [2]={str1,str2};` – chux - Reinstate Monica Jan 02 '17 at 03:34
  • even if there is 2 element is the FOR, the program quits ... on this loop. – Radar Blue Jan 02 '17 at 03:35
  • Chux. that was it . and thanx Albers the proper number of loops in the for statement. – Radar Blue Jan 02 '17 at 03:40
  • 1
    Given that the code, as shown, would not even compile, your claim that the program quits on the loop is spurious. Try providing a sample of ACTUAL code that demonstrates you problem. – Peter Jan 02 '17 at 03:40
  • 2
    Be *very* careful using `scanf` for string input. In case your user enters return without characters, or a forename or lastname greater than 11 characters you are in trouble. A better alternative is `fgets`, but you will still need to test for names that exceed the 12 characters you provide. – David C. Rankin Jan 02 '17 at 03:50
  • Program quits because you are printing strings by using `"%s"` format specifier, which needs null terminated strings. And your printing just character arrays. So its may be getting core dumped. First of all you should clear your basics about C-Strings and Arrays. And as it is pointed out in above comments use `char *wordarray [2]={str1,str2};` – Pushpendra Jan 03 '17 at 01:45

5 Answers5

2

You need to validate each read with scanf (or whatever function you use for user input) to insure you have valid data to work with. You should also provide a width limitation for the read to insure you do not read beyond the end of your array. (e.g. scanf ("%11s", str1)). You should look into using fgets for user input and remove the '\n' included by fgets in your buffer. This will help you avoid a number of pitfalls with scanf that usually plague new users, especially when taking mixed string and numeric input.

Other than that, you should also look to avoid using magic numbers in your code (e.g. char str1[12]). If you need a constant 12, then define one or declare an enum to create it.

Putting those pieces together, you could do something like:

#include <stdio.h>

#define LEN 12

int main (void) {

    char str1 [LEN] = "";
    char str2 [LEN] = "";
    char *wordarray[] = {str1, str2};
    int i, nwords = sizeof wordarray/sizeof *wordarray;

    printf ("Type your forname   : ");
    if (scanf ("%11s", str1) != 1) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }
    printf ("Type your last name : ");
    if (scanf ("%11s", str2) != 1) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }

    printf ("\nYour name is : %s %s\n", str1, str2);

    for (i = 0; i < nwords; i++){
        printf ("%s", wordarray [i]);
    }
    putchar ('\n');

    return 0;
}

Example Use/Output

$ ./bin/name
Type your forname   : david
Type your last name : rankin

Your name is : david rankin
davidrankin

Look things over, and consider the other answers and let me know if you have further questions. Also take my comment regarding zero input or input beyond 12 characters into consideration. This will help build robustness into your input handling.

If you would like to approach the input using fgets, you can improve your input handling a bit with the following:

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

#define LEN 12

int main (void) {

    char str1 [LEN] = "",
         str2 [LEN] = "",
         *wordarray[] = {str1, str2};
    size_t i, len = 0, nwords = sizeof wordarray/sizeof *wordarray;

    printf ("Type your forname   : ");
    if (!fgets (str1, LEN, stdin)) {    /* read with fgets/validate */
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }
    len = strlen (str1);                /* get length of str1     */
    if (str1[len-1] == '\n')            /* test for trailing '\n' */
        str1[--len] = 0;                /* overwrite with nulbyte */

    printf ("Type your last name : ");
    if (!fgets (str2, LEN, stdin)) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }
    len = strlen (str2);
    if (str2[len-1] == '\n')
        str2[--len] = 0;

    printf ("\nYour name is : %s %s\n", str1, str2);

    for (i = 0; i < nwords; i++){
        printf ("%s", wordarray [i]);
    }
    putchar ('\n');

    return 0;
}
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

You don't understand how array and pointer work. You should read this answer.

#include <stdio.h>

int main(void) {
  printf("Type your forname : ");
  char str1[12];
  { // we open a scope because ret don't need to be in function scope
    int ret = scanf("%11s", str1); // scanf need to know how many bytes are
    // available without count `\0` and you must send the array itself not the
    // address
    if (ret != 1) {                        // scanf don't set str1
      fprintf(stderr, "Error in input\n"); // stderr is the error stream
      return 1;
    }
  }

  printf("\nType your last name : ");
  char str2[12];
  {
    int ret = scanf("%11s", str2);
    if (ret != 1) {
      fprintf(stderr, "Error in input\n");
      return 1;
    }
  }

  printf("\n\nYour name is : ");
  printf("%s\t%s", str1, str2);
  printf("\n");

  char *word[2] = {str1, str2}; // we need an array of pointer
  for (size_t i = 0; i < sizeof word / sizeof *word; i++) { // size of array
    printf("%s", word[i]);
  }

  return 0;
}
Community
  • 1
  • 1
Stargateur
  • 24,473
  • 8
  • 65
  • 91
0

Shure I dont know how everything functions. That why I ask :) Thanks for the reply. I will investigate. With this information I will try to build a larger FOR-loop , so I can insert values in a 2D array. The user can add values to a 2d array then change the information text or numbers in the slots.

#include <stdio.h>
#define lenght 12                // corrected, define string format lenght

int main(){

char str1 [lenght];              // corrected, strings should have format lenght
char str2 [lenght];              // corrected, strings should have format lenght
char *wordarray [2]={str1,str2}; // corrected, add a * to wordarray[2]
int i;

printf ("Type your forname : ");
scanf ("%s",str1);               // corrected, skip the & in ("%s",&str1);
printf ("Type your last name : ");
scanf ("%s",str2);               // corrected, skip the & in ("%s",&str2);

printf ("\n\nYour name is : %s\t%s\n",str1,str2);

for (i=0;i<2;i++){               // corrected, i<2 must match the array elements
printf ("%s\t",wordarray [i]); 
} // end FOR

return 0;
} // end MAIN
  • wow, it works without the & in the ("%s",&str2) . I usually get an error when forgetting that & sign on the scanf`s. – Radar Blue Jan 02 '17 at 05:54
  • Read this [answer](http://stackoverflow.com/a/2528328/7076153), This work because it's an array but you should not do that. `&str` has type `char (*)[12]`, scanf expect `char *`, read this [question](http://stackoverflow.com/questions/1461432/what-is-array-decaying). – Stargateur Jan 02 '17 at 05:59
0

Ok. Had another go. Havent worked much with strings. This program has both strings and numbers in arrays and printed in FOR loops. I also tried to get the indevidual elements in the arrays available to the user, so he could change the values.

I guess my style is pretty wretched. but ... its what I got. Now concerning the GETS (str1), obtaining a string from the user. At the first use in the program it behaves normal. but the second time in the program I had to use GETS ("%s", str1) so it behaved proper. also an issue was to add specific numbers from a array detremined by the user. displayed in a for loop...

Another issue is to CLEAR the console screen after the JUMP . so the text doesnt flood the screen.

Comment : I agree David C. Rankin that validation of user data is important. Only tolerate character inputs on string requests, and numbers on integer request. Also return false input if "special characters" like slash or dots. I tried to read the origonal K&R C book and they talked about it, topics like turning all letters to small case or big case. but I had troubles getting the example code to run, maybe a C89 C11 compiler issue, I dont know.

#include <stdio.h>
//#include <string.h> // GCC32-C . mingw . compile
#define lenght 20    // Orbit_L75.Apartment_9

int main(){

int i,j,k,select,select2,*ptr;
char str1 [lenght];              
char str2 [lenght];             
char *wordarray [2]={str1,str2}; // character array must have a * asterix  pointer . 
int numarray [2];

printf ("Type your forname : ");
gets (str1); // gets (wordarray[0]) // alternative syntax       
printf ("Type your last name : ");
gets (str2);            

printf ("Enter your telephone number : ");            
scanf ("%d",&numarray[0]);     // assign a value to numarray slot 0
//scanf ("%d",(numarray+0));  // alternative syntax

printf ("Enter your age : ");
scanf ("%d",&numarray[1]); // assign a value to numarray slot 1
printf ("\n\n");

jump1 : 
printf ("=========================\n");
for (i=1;i<5;i++)
{printf ("%d\t",i);}
printf ("\n");

for (j=0;j<2;j++)
{printf ("%s\t",wordarray[j]);}
//printf ("%s\t",*(wordarray+j));} //  alternative syntax
printf ("\n");

for (k=0;k<2;k++)
{printf ("%d\t",numarray[k]);}
printf ("Sum = %d\n",(numarray[0]+numarray[1]));     // add numarray slot 0 and slot 1.
//printf ("Sum = %d",*(numarray+0)+*(numarray+1));  // alternative syntax
printf ("=========================\n");

printf ("\n\nSelect\n1: Change Telephone \n2: Change Age \n3: Change First Name \n4: Change Last Name \n5: RAM location\n");
scanf ("%d",&select);

if (select == 1)
{printf ("New number : ");
scanf ("%d",&numarray[0]);
//scanf ("%d",(numarray+0));               // alternative syntax
printf ("\n");}

else if (select == 2)
{printf ("New age : ");
scanf ("%d",&numarray[1]);
printf ("\n");}

else if (select == 3)
{printf ("New First Name : ");
scanf ("%s",str1); //problems with the display using GETS on the second run.
printf ("\n");} 

else if (select == 4)
{printf ("New Last Name : ");
scanf ("%s",str2);
printf ("\n");}

else if (select == 5)
{ // select2
{printf ("\nRAM location of : \n\t1. Telephone number\n\t2. Age\n\t3. First Name.\n\t4. Last Name\n");}
scanf ("%d",&select2);

if (select2 == 1)
{ptr = &numarray[0];
printf ("\nTelephone number\nValue in Decimal\t: %d\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}

else if (select2 == 2)
{ptr = &numarray[1];
printf ("\nAge\nValue in Decimal\t: %d\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}

else if (select2 == 3)
{ptr = &wordarray[0];
printf ("\nFirst Name\nValue in Text\t: %s\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}

else if (select2 == 4)
{ptr = &wordarray[1];
printf ("\nLast Name\nValue in Text\t: %s\nValue in Hexadecimal\t: %ph\nRAM location in decimal\t: %d\nRAM location in Hex\t: %ph\n\n\n",*ptr,*ptr,ptr,ptr);}

else if (select2 <1 || select2 > 4)
{printf ("\nValue is out of range, Try again .\n\n");}
} // end IF select2

else if (select <1 || select > 5)
{printf ("\nValue is out of range, Try again .\n\n");}

goto jump1;

return 0;
} // end MAIN
-1

str1 and str2 are effectively pointers.

wordarray is an array of chars. It should be an array of pointers to char.

Also in your scanf you're passing address of str1 and str2, but you should just pass str1 and str2.

Willis Blackburn
  • 8,068
  • 19
  • 36