i'm new to this c programming. all i wanna do is to make the user to enter the number of student, then input the name and address of the student. later i want it to print the name and the address. the program crashes after i input all the name and the address.
i don't know whether this program is wrong or my pc problem. thank you :) oh btw, i need to use array for this program.

#include <stdio.h>
#include <conio.h>

void main ()
{
	int i, n;
	char name[30][30];
	char add[30][30];

	printf ("Enter the number of student >> ");
	scanf ("%d", &n);

	for (i = 0;i < n; i++)
	{
		printf ("Enter the name of student %d >> ", i+1);
		scanf ("%s", &name[i][30]);
		printf ("Enter the address of student %d >> ", i+1);
		scanf ("%s", &add[i][30]);
	}

	for (i = 0; i < n; i++)
	{
		printf ("The name of student %d is >> %s", i+1, name[i][30]);
		printf ("The address of student %d >> %s", i+1, add[i][30]);
	}

	printf ("\n");
}

Edited 5 Years Ago by mameemonster: n/a

Comments
welcome to Daniweb
used code tags correctly on first post :)

lines 16 and 18 are wrong, you are passing a pointer to a single character not the whole string. Here's how to code it scanf ("%s", name[i]);

In addition,
You can remove this line

#include <conio.h> //non- standard library,also not portable

'main' should always return int, like this:

int main(void)

and return statement at the end.

return 0;

add

fflush(stdout);

after the printf statements,by doing that you'll force the output to be displayed on the screen even if the output buffer is not full.
And finally don't use 'scanf' while taking string inputs,use 'fgets' instead:

fgets(name[i],sizeof(name[i]),stdin);

If you use fgets() you will also have to remove the terminating '\n' that fgets() will add to the end of the string, assuming there was enough room in the buffer to hold it.

fgets(name[i],sizeof(name[i]),stdin);
if( name[i][strlen(name[i])] == '\n')
  name[i][strlen(name[i])] = '\0';

or you can do it like this

char* ptr;
fgets(name[i],sizeof(name[i]),stdin);
if( (ptr = strchr(name[i],'\n\)) != NULL)
   *ptr = '\0';

More than likely your program is crashing because you are asking scanf to enter a string when you only give it one character: scanf ("%s", &name[i][30]); . You must supply scanf with an array of characters: e.g. scanf ("%s", &name[i]); What you have declared char name[30][30] ; char add[30][30] is a pair of two dimensional character arrays: one two dimensional array of characters for the name and another for the address. The effect of the declaration is to allow you 30 names each with a character limit of 30 and 30 addresses each with a character limit of 30.

In a two dimensional array the rightmost value would correspond to the columns and the leftmost value would correspond to the row. In this situation, the leftmost value would indicate the name or the address: e.g., name , add.

If you use both values you are only referencing one of the values inside the row. In your case, just the last character of the row.

But a string is an array of characters; so, you must reference the row and not just the one column value in the row as you have done: name[i][30] . So, as Ancient Dragon said, just reference the row: name[i] without using the rightmost index. The printf function will look for the first instance of a null value and stop there.

So, it might be a good idea to initialize the arrays before asking for information:

// Initialize arrays with null values
    for (i = 0; i < 30; i++)
	for (n = 0; n < 30; n++)
	{
	    name[i][n] = '\0' ;
	    add[i][n] = '\0' ;
	}

This should work with scanf. If you don't want to mess with getting rid of the '\n', then just use gets. gets replaces the '\n' with a '\0' character which is a null character. But to keep you from getting confused. You can leave your code as is without using fgets or gets. Just change the lines where you enter the information to access the row name[i] instead of name[i][30] : line 16 and line 18.

Edited 5 Years Ago by hkdani: n/a

Comments
using "gets" is a bad idea.
#include <stdio.h>
#include <string.h>

int main (void)
{
	int i, n, m;
	char name[30][30];
	char add[30][30];

	printf ("Enter the number of student >> ");
	scanf ("%d", &m);
	
	for (i = 0; i < 30; i++)
		for (n = 0; n < 30; n++)
	{
	    name[i][n] = '\0' ;
	    add[i][n] = '\0' ;
	}

	for (i = 0;i < m; i++)
	{
		printf ("Enter the name of student %d >> ", i+1);
		scanf ("%s", &name[i]);
		printf ("Enter the address of student %d >> ", i+1);
		scanf ("%s", &add[i]);
	}
	
	for (i = 0; i < m; i++)
	{
		printf ("The name of student %d is >> %s\n", i+1, name[i][30]);
		fflush(stdout);
		printf ("The address of student %d >> %s\n", i+1, add[i][30]);
		fflush(stdout);
	}

	printf ("\n");
	return 0;
}

i make it this way. what is wrong with this? if i make it for 1 student. the printf working. but it said " the name of student 1 is >> null " and same for the address.

still crashed if i make it more than 1 student. thank you. :)

lines 30, 32

You are providing one character not a string name[i][30] . Use only the leftmost index to access the whole array of characters for the row as Ancient Dragon pointed out: string name[i] .

You don't need to use the fflush. Just keep it simple.

My bad, use the & operator.

Edited 5 Years Ago by hkdani: n/a

thank you so much hkdani :) but 1 tiny problem. well i think. why i cannot use space if i want to enter the name? if i using space, the word after the 1st one directly go into address then prompt me to enter the name of the 2nd student. thank you :)

use fgets or gets over scanf: it's safe and secure. scanf terminates when it finds a whitespace character. A space is a whitespace character. So, Diwakar wagle gave a good suggestion to use fgets. These two functions will include the spaces and terminate when receiving the newline character '\n' or when you hit the enter key. gets will remove the '\n' character so you don't have to. fgets will include the '\n' character.
If you want your program to advance a new line without using printf("\n") ; use fgets.

#include <stdio.h>

int main(void)
{
   char string[80];

   printf("Input a string:");
   gets(string);
   printf("The string input was: %s\n", string);
   return 0;
}

Edited 5 Years Ago by hkdani: n/a

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

int main (void)
{
	int i, n, m;
	char name[30][30];
	char add[30][30];

	printf ("Enter the number of student >> ");
	scanf ("%d", &m);
	
	for (i = 0; i < 30; i++)
		for (n = 0; n < 30; n++)
	{
	    name[i][n] = '\0' ;
	    add[i][n] = '\0' ;
	}

	for (i = 0;i < m; i++)
	{
		printf ("Enter the name of student %d >> \n", i+1);
		gets (name[i]);
		printf ("Enter the address of student %d >> \n", i+1);
		gets (add[i]);
	}
	
	for (i = 0; i < m; i++)
	{
		printf ("The name of student %d is >> %s\n", i+1, name[i]);
		printf ("The address of student %d >> %s\n", i+1, add[i]);
	}

	printf ("\n");
	return 0;
}

i edited to this. 1 more problem. after enter the number of student, it directly ask to insert address of the 1st student. like i'm entering blank input for the name of the 1st student. but it works for the 2nd student on so on.

Edited 5 Years Ago by mameemonster: n/a

Use fflush after your scanf or gets lines.

printf ("Enter the number of student >> ");
    scanf ("%d", &n);
    fflush(stdin) ;

..........

fgets (name[i], sizeof(name[i]), stdin);
	fflush(stdin) ;

..........
fgets (name[i], sizeof(add[i]), stdin);
	fflush(stdin) ;

You're getting unwanted characters from a previous function's return value.
fgets is preferred over gets. gets has security issues. fgets forces the limit on the size of the input(the second parameter). The first parameter is the destination, the second the limiting size, third parameter is the source. gets has no limiting size and could potentially overwrite memory.

Edited 5 Years Ago by hkdani: n/a

wow. it works great! thank you so much hkdani. problem solved. and thank you for all those helped me earlier. :)

Use fflush after your scanf or gets lines.

printf ("Enter the number of student >> ");
    scanf ("%d", &n);
    fflush(stdin) ;

..........

fgets (name[i], sizeof(name[i]), stdin);
	fflush(stdin) ;

..........
fgets (name[i], sizeof(add[i]), stdin);
	fflush(stdin) ;

I gave you positive rep for one of your previous posts -- I want it back! fflush() is only intended for output streams, not input streams, also a few compilers have implemented it for input streams. Never suggest using fflush(stdin) because its non-standard and not implemented by most compilers.

I have no control over feedback. But I do appreciate the feedback. I don't get too excited over feedback, one way or the other.

But I tried fflush(stdout) after the first scanf and it did not work. fflush(stdin) did. So, they must have been using scanf instead of fgets.

The behavior of the program was as described by the user. Using fflush(stdin) fixed the problem. Using fflush(stdout) left the problem as before. The user must have been using an ANSI compliant system.

However, your admonition for those not using ANSI compliant systems is duly noted and the following correction is posted according to your recommendations:

char cpInt[]= "000" ;

printf ("Enter the number of student >> ");
    fgets(cpInt, sizeof(cpInt), stdin);
    fflush(stdout) ;

n = atoi(cpInt) ;
if (!n)
{
    printf("Please enter a number.\n") ;
    return 0 ;
}

Thank you for the constructive pointers. They are always appreciated.

Of course fflush(stdout) didn't work because stdout is an output only stream. flush(stdin) worked for you only because your compiler allows it, not because its standard C language.

Well, it works with Microsoft's latest and greatest compiler 16.00.30319.01 for 80x86
And it works with Gnu C compiler 4.5.2, with Gnu C 3.4.5
Borland's 5.5.1 C Compiler.
Microsoft's Compiler 12.00.8804
Borland's old Turbo C 2.01
Borland's C++ 5.82

I might have to dig out one of my four working Apple IIe's to find a compiler it doesn't work on.

Edited 5 Years Ago by hkdani: n/a

Though, the thread has been marked solved, I would like to point few things out.

If you don't want to mess with getting rid of the '\n', then just use gets.

No, never use 'gets()' while taking strings as input(see why).People say don't use 'scanf' because it shows similar behavior to that of 'gets'.'fgets' is much more safer, and you should remove the trailing '\n' character as 'Ancient Dragon' suggested.
And this one is for 'hkdani'.

Comments
Leaves helpful comments giving insights into the intracies of important principles in the programming language.

Well, it works with Microsoft's latest and greatest compiler 16.00.30319.01 for 80x86
And it works with Gnu C compiler 4.5.2, with Gnu C 3.4.5
Borland's 5.5.1 C Compiler.
Microsoft's Compiler 12.00.8804
Borland's old Turbo C 2.01
Borland's C++ 5.82

I might have to dig out one of my four working Apple IIe's to find a compiler it doesn't work on.

Showing that multiple compilers do not follow the standard is not proof that it works for all compilers. It simply proves that the compilers don't follow the standard. And if you continue to rely on undefined behavior to work a certain way, I'd love to see what happens when you write some critical software for your job on a compiler that doesn't implement undefined behavior to your needs. It could be weeks before you remember this thread...

This question has already been answered. Start a new discussion instead.