Can u help me with this?
Here's the problem.
Everytime i input just 1 word...it works fine.
[IMG]http://img148.imageshack.us/img148/2503/26168475.jpg[/IMG]
but when i enter 2 words this will happen...
[IMG]http://img706.imageshack.us/img706/6625/49110093.jpg[/IMG]

#include <stdio.h>

struct Student{      
       char course[5];
       char subject[5];
       char name[20];
       float units[8];
       float grade[8];
       float qpi[3];
       }Stud[3];
       
int main()
{
    float grade = 0.0;
    float unit = 0.0;
    float total = 0.0;
    int n,i,x,y;
    
    for(i = 0; i < 3; i++)
    {
          printf("\nStudent [%d]\n",i+1);
          printf("Student name: ");
          scanf("%s",Stud[i].name);
          printf("Course: ");
          scanf("%s",&Stud[i].course);
          printf("Number of Subjects: ");
          scanf("%d",&n);
    
          for(x = 0; x < n; x++)
          {
                printf("Subject%d: ",x);
                scanf("%s",&Stud[x].subject[x]);
                printf("Units: ");
                scanf("%f",&Stud[x].units[x]);
                unit+=Stud[x].units[x];
                printf("Grade: ");
                scanf("%f",&Stud[x].grade[x]);
                grade = Stud[x].units[x] * Stud[x].grade[x];
                total += grade;             
          }
          Stud[i].qpi[i] = total / unit;
          printf("\t\t%s = (qpi is: %.2f)\n", Stud[i].name, Stud[i].qpi[i]);          
    }          
    printf("\n");
    for(y = 0; y < 3; y++)
    {
          printf("\t\t%s = (qpi is: %.2f)\n", Stud[y].name, Stud[y].qpi[y]);
    }
    
getchar();
getchar();
}

Edited 6 Years Ago by DoEds: n/a

#
printf("\nStudent [%d]\n",i+1);
printf("Student name: ");
scanf("%s",Stud[i].name);

printf("Course: ");
scanf("%s",[B]&[/B]Stud[i].course);

/* Course is a char array, so the name of the array is the address of the base of the array. Delete the '&'.
*/

I did not review the rest of your code. If it still have problems you can't fix, post back.

Please use gets() instead of scanf() if you expect spaces in the user input. scanf() does not handle spaces the way you want it to work.

Comments
here'yellow box for gets()
Rule #1, Day #1, Basic C Programming Introduction 101 (Programming for Poets): Don't use gets().

Please use gets() instead of scanf() if you expect spaces in the user input. scanf() does not handle spaces the way you want it to work.

gets() is not an option, because there's no way of controlling how much data can be inputed. There's no way of using it safely.
scanf() is an option to read input string, but a mischiefing one.
A better option to read string input would be fgets().

Please use gets() instead of scanf() if you expect spaces in the user input. scanf() does not handle spaces the way you want it to work.

gets() is not an option, because there's no way of controlling how much data can be inputed. There's no way of using it safely.
scanf() is an option to read input string, but a mischiefing one.
A better option to read string input would be fgets().

gets() and scanf("%s", ...) are functionally identical. See this to understand why you never use either.

Well, for a homework I don't think you really need to worry about flushing your data after reading something in just because you did not want to overflow in your input. I agree in professional world they should be avoided.

Besides, gets() and scanf() are not functionally identical. scanf() splits the input on a space and gets() doesn't. And that's what the OP's original problem was. The only quick alternative to scanf() to fix his problem (without having to add additional code to handle flushing etc) is to use gets(), that's why I suggested it. But I guess I should have added a disclaimer with it as well. :)

Edited 6 Years Ago by shah1248: n/a

Functionally identical means they will both overwrite memory with wild abandon and laugh at you when your program crashes. And there's nothing you can do to prevent them from doing it.

Comments
haha

gets() and scanf("%s", ...) are functionally identical. See this to understand why you never use either.

scanf() does accept width doesn't it? It can be made safe to use to read a string by just adding width to the string specifier, but not gets()

I tried using gets() but the problem occurs at 2nd loop...
And also it wont work at

#
printf("Subject%d: ",x);
#
scanf("%s",&Stud[x].subject[x])

Here's my code now...
At the put gets() dummy at the end of the loop...
I dunno how it worked...

My problem now is to sort the names with from highest to lowest QPI...
zzzzzz...Im tired...

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

#define NOS 3 //number of subjects

struct container{
       char name[20];
       float sort[3];
       }S_list[3];

struct Students{      
       char Course[5];
       char Subject[5];
       char Name[20];
       float Units[5];
       float Grade[5];
       float QPI[3];
       }Stud[3];
       
int main()
{
    float comp_Grade = 0;
    float unit_Accu = 0;
    float grade_Accu = 0;
    char dummy[10];
    
    
    for(int i=0;i<3;i++)
    {
          
          printf("[%d]\n Student name: ",i+1);
          gets(Stud[i].Name);
          printf(" Course: ");
          gets(Stud[i].Course);

          for(int j=0;j<NOS;j++)
          {
                printf("   Subject[%d]: ",j+1);
                scanf("%s",&Stud[j].Subject[j]);
                printf("\tUnits: ");
                scanf("%f",&Stud[j].Units[j]);
                unit_Accu+=Stud[j].Units[j];
                printf("\tGrade: ");
                scanf("%f",&Stud[j].Grade[j]);
                comp_Grade = Stud[j].Units[j] * Stud[j].Grade[j];
                grade_Accu += comp_Grade;             
          }
          Stud[i].QPI[i] = grade_Accu / unit_Accu;
          printf("\t\t%s = (qpi is: %.2f)\n", Stud[i].Name, Stud[i].QPI[i]);   
          
          gets(dummy); 
    }          
    printf("\n\n");
    printf("\t\t=========================\n");
   
    for(int k=0;k<3;k++)
    {
          printf("\t\t%s\n has a QPI of: %.2f)\n", Stud[k].Name, Stud[k].QPI[k]);
    }
    
    for (int y=0;y<3;y++)
    {
        for (int x=0;x<3;x++)
        {
            if (Stud[y].QPI[y]<Stud[x-1].QPI[x-1])
            {S_list[y].sort[y]=Stud[y].QPI[y];
            strcpy(S_list[y].name,Stud[y].Name);}
            else
              { S_list[y].sort[y]=Stud[y].QPI[y];
               strcpy(S_list[y].name,Stud[y].Name);}
        }
    }
    printf("\n\n");
    for (int y=0;y<3;y++)
    {
        printf(" %s \t\t%.2f\n",S_list[y].name,S_list[y].sort[y]);
    }

getchar();
getchar();
}

Edited 6 Years Ago by DoEds: n/a

You don't have to index the strings in our structure while taking the input. scanf("%s",&Stud[j].Subject[j]); This is wrong. What you want is to enter the subject for the jth student. So you need to index only the Stud array and not the Subject inside that structure. So it should be scanf("%s",Stud[j].Subject); Also you don't need the & (reference) to Subject since Subject represents the address of the start of the Subject string anyway.

Also are you sure you want the Units and Grade etc to be arrays or just one variable? If you really intend for them to be arrays, then you will have to run a small loop (where you are currently inputting the values for Units and Grades) and use that loop counter as index into the Units instead of using j, because j is for indexing into the Stud array and you will need another index to index into the Units and Grades arrays inside each of the Stud structure.

Also you need to revisit the definition of your structures. They look wierd.

Edited 6 Years Ago by shah1248: n/a

I've been reading about gets() and scanf() ...
I learn that they're both not safe in reading strings...instead using fgets() but i don't how to use fgets() to read inputs using a structure...

Edited 6 Years Ago by DoEds: n/a

You use it in a similar way to gets except you specify the maximum size of the char array you are reading into.
Take line 33:

fgets(Stud[i].Name,sizeof(Stud[i].Name),stdin);
(or you could put in 20 for the sizeof(Stud[i].Name) portion)
(last parameter is there in case you wanted to get input from a file, so you just need stdin to get it from the input stream)

Just be aware that fgets will take in a '\n' character into the string/char arr when you press enter, so you may have to step through your char arrays and substitute a '\0' for the '\n' (fgets will append a '\0' to the end of the input anyway but this way you terminate it at the proper point).

Edited 6 Years Ago by jonsca: n/a

Awkie...Thanks this is helpful...
btw, How will i substitute '\0' for '\n'?

int i;
for (i= 0; i < array.length; i++){
if (array[i] == '\0') array[i] = '\n';
}

My C coding skills are very rusty but that is the general idea, you might have to tweak it a little bit to make it compile haha (I don't remember if C uses .size or .length for arrays..).

(I don't remember if C uses .size or .length for arrays..).

Neither lol.

int i;
for (i = 0;array[i] !='\0';i++)
{ 
    if(array[i] =='\n')
       array[i] = '\0';
}

Edited 6 Years Ago by jonsca: n/a

Neither lol.

int i;
for (i = 0;array[i] !='\0';i++)
{ 
    if(array[i] =='\n')
       array[i] = '\0';
}

Or maybe:

l = strlen(array)-1
if (array[l] == '\n') array[l] == '\0';

Saves a for loop.

That seems reasonable, but what if the buffer is 20 characters and the user only enters 4 and hits enter?

Comments
Are you being silly, or are you having a brain fart? ;o)

That seems reasonable, but what if the buffer is 20 characters and the user only enters 4 and hits enter?

What would the value of strlen() return in that case?

Comments
Yup

Whew, for some reason I confused C with objective-c .. of course the array isn't an Object and doesn't have 'size' or 'length'. I feel silly - Next time I'll compile first. Neat trick WaltP.

edit: just so the OP doesn't copy paste, there is a typo in Walt's snippet, the second == should be =

Edited 6 Years Ago by BestJewSinceJC: n/a

hello there, you are apparently getting closer to the success of your program.

Would it be alright to suggest? I bet you can also use fflush(stdin); before your first gets() statement. That will help you in your future encounter towards string inputs.

Good Luck!

Comments
i thought this was a joke. then i realized it was not a joke.

hello there, you are apparently getting closer to the success of your program.

Would it be alright to suggest? I bet you can also use fflush(stdin); before your first gets() statement. That will help you in your future encounter towards string inputs.

Good Luck!

You are the one that will need a lot of luck if you think it is acceptable to make use of fflush(stdin) and gets().
fflush() is undefined if you give it stdin as an argument.
gets() is not an option even for throw away code.
It would be better if you do not touch the keyboard at that point.

Edited 6 Years Ago by Aia: n/a

You are the one that will need a lot of luck if you think it is acceptable to make use of fflush(stdin) and gets().
fflush() is undefined if you give it stdin as an argument.
gets() is not an option even for throw away code.
It would be better if you do not touch the keyboard at that point.

In other words, gets() and fflush().

It's good to give an explanation, not just tell people something and they just have to believe you. None of us have credibility to new posters.

In other words, gets() and fflush().

It's good to give an explanation, not just tell people something and they just have to believe you. None of us have credibility to new posters.

That's why you are here.
On the other hand I only give what I want to give. A simple search in this forum or even Googling for the terms should provide enough information for the mind that wants to be instructed.

Edited 6 Years Ago by Aia: n/a

Why google for something they don't believe is a problem? Just because someone says don't is not enough of a reason.

Just sayin' :icon_wink:

And if that's why I'm here, why post at all if I'm just gonna have to clean up after you? I don't even clean up after my kids, and you're old enough to know better :icon_twisted:

Funny thing, Walt, i've noticed your own recent posts where you do exactly the same thing.

such as this one here, where your only response to some guy's crap code was to tell him that it's full of problems and he needs to refrain from posting.

Please ignore yila's code. It is full of problems.

yila, please refrain from posting (supposedly) working code for people. They learn nothing so you are hurting more than helping. Especially when you use bad coding practices.

C Forum "Half Pyramid" thread post #8, March 07 2010

No explanation of why it was bad. Not even an explanation of *what* was wrong.

Now I wouldn't ever call you out on it because i totally agree with you. I'm tired of explaining the same things over and over to every noob and his brother. Crap code is crap code, and being nice and patient about it doesn't change the fact that most of them aren't listening anyhow except long enough to get the quickest and easiest answer.

And as for credibility ... that's a non issue. Veteran posters like yourself with thousands of posts and hundreds of "solved threads" don't NEED to establish credibility. At least not for newbie posters asking basic "why doesn't my program work?????" questions.


.

Edited 6 Years Ago by jephthah: n/a

Comments
I like the part about..."every noob and his brother". And how about a couple posts above that one?
they do to newbies. Veterans are still unknowns.

Why google for something they don't believe is a problem? Just because someone says don't is not enough of a reason.

And that's not my problem. I don't post for the ignorant that doesn't care of being ignorant, but rather for that one coming behind, reading much later, wanting to know and not be mislead.

And if that's why I'm here, why post at all if I'm just gonna have to clean up after you? I don't even clean up after my kids, and you're old enough to know better :icon_twisted:

You misunderstood me. That's why you here, because any time it strikes your fancy, that's what you like to do. But it is OK when you don't feel like.

Edited 6 Years Ago by Aia: n/a

Comments
Makes sense....

Neither lol.

int i;
for (i = 0;array[i] !='\0';i++)
{ 
    if(array[i] =='\n')
       array[i] = '\0';
}

This won't generate desired output in all cases, let me illustrate this with an example:

Case I: Using WaltP's approach to remove the newline character

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

int main()
{
  char str[80] = "Hello,\n";
  char *p;
  
  /* let p point to nul-terminator */
  p = str + strlen(str);
  
  printf("Enter your name: ");
  
  /* get a string and add it to the end of str */
  fgets(p, sizeof(str) - strlen(str), stdin);
  
  /* let p point to beginning */
  p = str;
  
  printf("Output:\n\n");
  
  /* WaltP's approach */
  size_t l = strlen(str) - 1;
  if ( str[l] == '\n' ) str[l] = '\0';
  
  printf("%s", str);
  
  return 0;
}

This would generate the following output, when the username WaltP would be entered:

Output:

Hello,
WaltP

Case II: Using Jonsca's approach to remove the newline character

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

int main()
{
  char str[80] = "Hello,\n";
  char *p;
  
  /* let p point to nul-terminator */
  p = str + strlen(str);
  
  printf("Enter your name: ");
  
  /* get a string and add it to the end of str */
  fgets(p, sizeof(str) - strlen(str), stdin);
  
  /* let p point to beginning */
  p = str;
  
  printf("Output:\n\n");
  
  /* Jonsca's approach */
  int i;
  for (i = 0; str[i] != '\0'; i++) {
    if ( str[i] =='\n' )
      str[i] = '\0';
  }

  printf("%s", str);
  
  return 0;
}

This code would generate the following output, when the username WaltP would be entered:

Output:

Hello,

In the end I would prefer WaltP's approach, because I find it the most robust one to accomplish the task, without getting unwanted side-effects in certain situations.

Edited 6 Years Ago by mvmalderen: n/a

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