so i am still taking the Edx C courses, and i am currently trying to do an exercise in which i make a program which takes a character input (for the variable type) and an integer for the number of variables. (for example "i 100" would mean 100 integers, which would = 400 bytes usually). My program works fine for me, but when i input it to the website, it says that it doesn't input anything at all. here is the link to the series of exercises: https://courses.edx.org/courses/course-v1:Dartmouth_IMTx+DART.IMT.C.03+1T2020/courseware/5c40ed165b45423496c1c8c8fdca08d9/91f8edcd857f410b82baa1860866f4ae/1?activate_block_id=block-v1%3ADartmouth_IMTx%2BDART.IMT.C.03%2B1T2020%2Btype%40html%2Bblock%402118ce4a1e134f6099827cf836e7a2d4 and the one i am doing is the 'memory usage displayed' one. here is my code:

Code:

#include <stdio.h>

int main() {
   int i=0;
   int totalMem = 0;
   int memDat [3];
   for(i=0; i<2; i++) {
      memDat[i] = 0;
   }
   int numEntries = 0;
   char dataType = '\0';
   int entriesSize;

   scanf("%c %d", &dataType, &numEntries);

   if(dataType == 'i') {
      entriesSize = sizeof(int);
   } else if(dataType == 's') {
      entriesSize = sizeof(short);
   } else if(dataType == 'c') {
      entriesSize = sizeof(char);
   } else if(dataType == 'd') {
      entriesSize = sizeof(double);
   }
   
   /*
   calculate total mem used
   separate mem used into megabytes (millions), kilobytes(thousands), and bytes(leftover)
   */

   totalMem = numEntries * entriesSize;

   memDat[0] = totalMem / 1000000;
   totalMem = totalMem - (memDat[0] * 1000000);
   memDat[1] = totalMem / 1000;
   totalMem = totalMem - (memDat[1] * 1000);
   memDat[2] = totalMem;

   if(memDat[0] > 0) {
      printf("%d MB and ", memDat[0]);
   }
   if((memDat[0] > 0) || (memDat[1] > 0)) {
      printf("%d KB and ", memDat[1]);
   }
   printf("%d B", memDat[2]);

   return 0;
}
modified code still not working:

Code:

#include <stdio.h>

int main() {
   int i=0;
   int totalMem = 0;
   int memDat [3];
   for(i=0; i<2; i++) {
      memDat[i] = 0;
   }
   int numEntries = 0;
   char dataType = '\0';
   int entriesSize;

   scanf("%c %d", &dataType, &numEntries);

   if(dataType == 'i') {
      entriesSize = sizeof(int);
   } else if(dataType == 's') {
      entriesSize = sizeof(short);
   } else if(dataType == 'c') {
      entriesSize = sizeof(char);
   } else if(dataType == 'd') {
      entriesSize = sizeof(double);
   }
   
   /*
   calculate total mem used
   separate mem used into megabytes (millions), kilobytes(thousands), and bytes(leftover)
   */

   totalMem = numEntries * entriesSize;

   memDat[0] = totalMem / 1000000;
   totalMem = totalMem - (memDat[0] * 1000000);
   memDat[1] = totalMem / 1000;
   totalMem = totalMem - (memDat[1] * 1000);
   memDat[2] = totalMem;

   if(memDat[0] > 0) {
      printf("%d MB and ", memDat[0]);
   }
   if((memDat[0] > 0) || (memDat[1] > 0)) {
      printf("%d KB and ", memDat[1]);
   }
   printf("%d B\n", memDat[2]);

   return 0;
}
You can't do that with scanf. The scanf function is basically useless. People should not use it.
The code looks fine. My guess is whatever automated system checks the code is deciding that you haven't written the "intended" solution. The link requires a login to access so I can't guess at what it actually wants, or even how it's trying to grade your code.

One time in college, there was an assignment that could potentially be implemented in one of two ways. I asked which approach we should use and got told something vague. They provided a sample program that implemented the assignment. This course used Java. So fine, I thought, I'll decompile their sample. They had used an obfuscator. It took a whole extra five minute to identify which approach they used.

My point is that turning in something more sophisticated than what the teacher wants can get you a bad grade, so sometimes the real problem you have to solve is not the problem posed in the assignment, but rather figuring out what the teacher is thinking.
What Mateo means to say scanf is limited. There are a couple of problems with it.
For example, you can use it to read strings from stdin, but it's dangerous.
Here's what I mean:

Code:

char buff[42];
scanf("%s",buff);

If the user types something larger than your buffer, scanf will fill the buffer past the end.

Here's a better solution for taking a string from input:

Code:

char buff[42];
fgets(buff,40,stdin);

Here fgets stops reading at 40 characters, or a newline. No buffer overflows.
Hi, I'm just passing by to say that scanf() can totally do that with %40s. You can even restrict the character set if you want, with %40[a-z] if you feel like it. It's nowhere near as useless as it might seem at first!

Have you noticed that your program does not output a newline? I don't know if it's relevant, but automated systems that check answers might be sensitive to that. (I've tried to read the exercise but got to a login page.)

Also your memDat array is not entirely initialized since you leave memDat[2] to its default value which can be anything. The usual way to write the loop here is for(i = 0; i < number_of_elements; i++) which would be 3 here instead of 2.
Lephe wrote:
Also your memDat array is not entirely initialized since you leave memDat[2] to its default value which can be anything. The usual way to write the loop here is for(i = 0; i < number_of_elements; i++) which would be 3 here instead of 2.

I mean, I would have just done:

Code:
int memDat[] = {0, 0, 0};
Yes of course, or even = { 0 }; this remark was just trying to be useful to get loops right in general. (Also the element is eventually set anyway.)
Lephe wrote:
Hi, I'm just passing by to say that scanf() can totally do that with %40s. You can even restrict the character set if you want, with %40[a-z] if you feel like it. It's nowhere near as useless as it might seem at first!

Have you noticed that your program does not output a newline? I don't know if it's relevant, but automated systems that check answers might be sensitive to that. (I've tried to read the exercise but got to a login page.)

Also your memDat array is not entirely initialized since you leave memDat[2] to its default value which can be anything. The usual way to write the loop here is for(i = 0; i < number_of_elements; i++) which would be 3 here instead of 2.


Yeah, that's true.
The other problem I can think of off the top of my head is if the input fails. Then, the stream pointer (file pointer, really) could get left in an indeterminate position.
So maybe scanf isn't too bad after all; I was just trying to guess what Mateo meant.
Michael0x18 wrote:
So maybe scanf isn't too bad after all; I was just trying to guess what Mateo meant.


He is using %d and %c, both of which are prone to many issues. Here's a nice article telling you why you shouldn't use it because I don't like retyping things.

http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
This is a nice article, although I'm not sure the takeaway of "don't use scanf()" is deserved, as the other solutions are not devoid of problems either. The strcspn() is section 3 fails spectacularly on non-newline inputs (like the side note in section 2), strtol() is extremely verbose (whereas %[0-9] can guarantee the input is valid), and scanf() is very useful overall if you just want to parse a string in one go or reject it.

Rule 1 is spot on though, and extremely well worded. getline() + sscanf() or reading from a file combined with sscanf() are much safer. Wondering what's left in the input stream after a scanf() is admittedly not enjoyable.

I digress though, sorry for the rant. I hope the original problem will be solved in the meantime. ^^
Lephe wrote:
The strcspn() is section 3 fails spectacularly on non-newline inputs

No strcspn returns the length if no newline is found. Anyway I'll stop distracting this thread.
A common issue is that the automated testing system will delimit the input test cases with newlines. Have you tried adding a '\n' to your scanf string. I know others have pointed out the security vulnerabilities and other flaws that come with using scanf, but just stick to what your instructor has told you to do for this specific assignment.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement