Up vote 0 down vote favorite share g+ share fb share tw.
I am new to the C programming language and trying to improve by solving problems from the Project Euler website using only C and its standard libraires. I have covered basic C fundamentals(I think), functions, pointers, and some basic file IO but now am running into some issues. The question is about reading a text file of first names and calculating a "name score" blah blah, I know the algorithm I am going to use and have most of the program setup but just cannot figure out how to read the file correctly.
The file is in the format "Nameone","Nametwo","billy","bobby","frank"... I have searched and searched and tried countless things but cannot seem to read these as individual names into an array of strings(I think thats the right way to store them individually? ) I have tried using sscanf/fscanf with %^\",. I have tried different combos of those functions and fgets, but my understanding of fgets is everytime I call it it will get a new line, and this is a text file with over 45,000 characters all on the same line.
I am unsure if I am running into problems with my misunderstanding of the scanf functions, or my misunderstanding with storing an array of strings. As far as the array of strings goes, I (think) I have realized that when I declare an array of strings it does not allocate memory for the strings themselves, something that I need to do. But I still cannot get anything to work.
Here is the code I have now to try to just read in some names I enter from the command line to test my methods. This code works to input any string up to buffer size(100): int main(void) { int i; char input100; char* names10; printf("\nEnter up to 10 names\nEnter an empty string to terminate input: \n"); for(int I = 0; I PLEASE advise me as to how to read it in with format. I have previously used sscanf on the input buffer and that has worked fine, but I don't feel like I can do that on a 45000+ char line?
Am I correct in assuming this? Is this even an acceptable way to read strings into an array? I apologize if this is long and/or not clear, it is very late and I am very frustrated.
Thank anyone and everyone for helping, and I am looking forward to finally becoming an active member on this site! C string file-io sscanf fscanf link|improve this question asked Feb 12 at 7:10Joe Roszkowski31.
There are really two basic issues here: Whether scanning string input is the proper strategy here. I would argue not because while it might work on this task you are going to run into more complicated scenarios where it too easily breaks. How to handle a 45k string.
In reality you won't run into too many string of this size but it is nothing that a modern computer of any capacity can't easily handle. Insofar as this is for learning purposes then learn iteratively. The easiest first approach is to fread() the entire line/file into an appropriately sized buffer and parse it yourself.
You can use strtok() to break up the comma-delimited tokens and then pass the tokens to a function that strips the quotes and returns the word. Add the word to your array. For a second pass you can do away with strtok() and just parse the string yourself by iterating over the buffer and breaking up the comma tokens yourself.
Last but not least you can write a version that reads smaller chunks of the file into a smaller buffer and parses them. This has the added complexity of handling multiple reads and managing the buffers to account for half-read tokens at the end of a buffer and so on. In any case, break the problem into chunks and learn with each refinement.
EDIT #define MAX_STRINGS 5000 #define MAX_NAME_LENGTH 30 char* stripQuotes(char *str, char *newstr) { char *temp = newstr; while (*str) { if (*str! = '"') { *temp = *str; temp++; } str++; } return(newstr); } int main(int argc, char *argv) { char fakeline = "\"Nameone\",\"Nametwo\",\"billy\",\"bobby\",\"frank\""; char *token; char namebufferMAX_NAME_LENGTH = {'\0'}; char *name; int index = 0; char nameArrayMAX_STRINGSMAX_NAME_LENGTH; token = strtok(fakeline, ","); if (token) { name = stripQuotes(token, namebuffer); strcpy(nameArrayindex++, name); } while (token! = NULL) { token = strtok(NULL, ","); if (token) { memset(namebuffer, '\0', sizeof(namebuffer)); name = stripQuotes(token, namebuffer); strcpy(nameArrayindex++, name); } } return(0); }.
Thanks! This helped a ton..I still have some questions though. In regards to your #1 above, why is this not a reasonable strategy?
What could break and what exactly would be a more complicated scenario? And second, using strtok works perfectly to get each name seperated, but I am having issues stripping the quotation marks. In my function, I think I should obviously be passing it a pointer to the string that is the name with quotes around it.
I am getting confused on the strategy to strip the quotes and what I should return? A new char array for the name? Or edit the string itself?
Thanks! – Joe Roszkowski Feb 13 at 4:11 I think ive gotten it, My method is to pass the token pointer to a function which starts at name1 and copys each char into a temp char array until it reaches a quotation mark. I then allocate memory for the length of this temp array in my main names array of strings and copy the temp string into the main string array.
It works well, but is this a good way to do this? Thanks again – Joe Roszkowski Feb 13 at 4:55 That's basically it. Passing name1 is ugly since you are assuming it will be a quote.
I started to help you with the one function but there are so many funky little gotchas with strtok() that it would have taken longer to explain it than code it. It sounds like have most of it so I don't think I ruined anything for you. This is just a hack so there is still room for improvement anyway.
– Duck Feb 13 at 6:06 You have been a ton of help, thanks again I think I get it now. – Joe Roszkowski Feb 13 at 14:46.
Fscanf("%s", input) reads one token (a string surrounded by spaces) at a time. You can either scan the input until you encounter a specific "end-of-input" string, such as "! ", or you can wait for the end-of-file signal, which is achieved by pressing "Ctrl+D" on a Unix console or by pressing "Ctrl+Z" on a Windows console.
The first option: fscanf("%s", input); if (input0 == '! ') { break; } // Put input on the array... The second option: result = fscanf("%s", input); if (result == EOF) { break; } // Put input on the array... Either way, as you read one token at a time, there are no limits on the size of the input.
Something like this: #include #include int main(void) { char mydata = "\"John\",\"Smith\",\"Foo\",\"Bar\""; char namebuffer20; unsigned int i, j; int begin = 1; unsigned int beginName, endName; for (i = 0; I.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.