Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. The bad and the ugly...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2007
    Location
    Oz... No??? Neverland then?
    Posts
    142
    Rep Power
    0

    UPDATE: C89 syntax is stupid. for() loop workaround?


    LAST COMMENT HAS MY QUESTION.




    Hey,

    I'm taking a C/C++ programming class this year at university. For our first assignment our teacher wants us to grab a file name (inputted by the user) of letters, one per line, and he wants us to sort it alphabetically then spit out another file with '_out' appended to the end of it.

    here's my code so far:

    PHP Code:
    //precompile layer. cleaner code.  #include <stdio.h>  #include <string.h>  #include <stdlib.h>  //#include <ctype.h>  //#include <fstream>    #define MAXCHAR 256 //size of memory location?? keeps code cleaner    int main(void)  {      //declaration variables      FILE *filename;      char *fname = NULL;      int n = 0; //used for prompting user for file name      int x = 0; //counter for length of file      char temp;             //      //allocate memory for size of filename (char = 1 bit)      fname = (char *)malloc(MAXCHAR * sizeof(char));            //      //prompt user for file name and continue to do so until a valid file name is given      while (n != 1)          {              printf("Enter file name: ");              scanf("%s", fname);                            //if statement w/ for loop inside of it              //go through each char, if \0 before . append ".txt" to the file              //else just open it                            filename = fopen(fname, "r"); //filename is just the handle to that file. have to go through filename for IO operation                            if (filename == NULL)                  {                      printf("Please enter a valid file name.\n");                  }              else                      {                      printf("File was successfully opened!\n");                      n = 1;                  }          }          //printf("%s\n", fname);          //          //while loop used to find the overall length of the file           while (fscanf(filename, "%c\n", &temp) != EOF  ) //fscanf wants the address to store the character "&temp" not just "temp"              {                  x++;              }                        //          //close and reopen file to move flag-bit to beginning of file          fclose(filename);              filename = fopen(fname, "r");                    //allocate memory in master array based on file length (int x earlier)          char **letters = (char *)malloc(x * sizeof(char));                    //read each character into array          //create filename_out.txt          //bubble sort          //write sorted array to file                            fclose(filename);      free(fname);      return(0);        } 
    i'm getting an error "expect ';' before 'type.' what am i missing? if i comment out that line everything works perfectly as planned.

    Code:
    		//allocate memory in master array based on file length (int x earlier)  		char **letters = (char *)malloc(x * sizeof(char));
    also, as a little extra, i wanted to include a portion that would recognize if the user inputted filename was missing the '.txt' at the end of it and add it if it wasn't there. any pointers on that?

    thanks
    ~Tim


    EDIT: im sorry, i tried getting it to clean up my code, but neither the # button or the php seem to do anything. HOW CAN I POST MY CODE NEATLY?!
    Last edited by ChokolAwt; September 3rd, 2012 at 05:08 PM. Reason: next question!
    "Life is not a journey with the intent on arriving at the finish line in a pretty and well preserved body. But rather to skid in broadside, totally worn out, thoroughly used up and loudly proclaiming, "Wow! What a ride!" -Anonymous
    Halo! || Diablo 2 LOD Modding || OLGA's BACK!
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Using code tags (I just type the tags in myself; I've never tried any special formatting buttons), copy and paste the formatted code from your regular text editor that you write your code in in between the open and close code tags (ie, between [code] and [/code]). I'm not sure why it sometimes replaces newlines with spaces, but I've seen it happen when copying from one forum to another.


    Question: what kind of strings are you using? The basic string class or C-style strings?

    Assuming C-style strings (which was also the norm in C++ before 1998), you get the length of the string to be copied and add one for the null-terminator (the char '\0' which marks the end of the string; this is absolutely important). Allocate a block of memory using that length-plus-one value -- malloc for C, new for C++. Then use a string function to do the copy, such as strcpy.

    Obviously, until you can make your code readable, I'm just guessing that that may have been the answer you were looking for. But at least you realized you had a problem, which is much more than most would do.

    PS
    OK, I just looked at this:
    char **letters = (char *)malloc(x * sizeof(char));

    Are you trying to create a two-dimensional array of char such that it serves as a one-dimensional array of strings?

    In C, 2-D arrays can be viewed as arrays of arrays, such that each row is an array in itself with each column being an element in that array. So each row would be one string.

    If that's all the case, then do the malloc in two steps:
    1. First create the rows. Figure out how many strings you want and malloc letters for that, only you'd want each element to be the size of a char pointer (char*).
    2. As you process through and discover the size of the next string to be copied in, that is when you malloc for the size of string plus one elements of size char and assign that pointer to the row.

    I hope that made sense.
    Last edited by dwise1_aol; August 31st, 2012 at 07:23 PM.
  4. #3
  5. The bad and the ugly...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2007
    Location
    Oz... No??? Neverland then?
    Posts
    142
    Rep Power
    0
    Code:
    //precompile layer. cleaner code.
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    //#include <ctype.h>
    //#include <fstream>
    
    #define MAXCHAR 256 //size of memory location?? keeps code cleaner
    
    int main(void)
    {
    	//declaration variables
    	FILE *filename;
    	char *fname = NULL;
    	int n = 0; //used for prompting user for file name
    	int x = 0; //counter for length of file
    	char temp; 
    	
    	//
    	//allocate memory for size of filename (char = 1 bit)
    	fname = (char *)malloc(MAXCHAR * sizeof(char));
    	
    	//
    	//prompt user for file name and continue to do so until a valid file name is given
    	while (n != 1)
    		{
    			printf("Enter file name: ");
    			scanf("%s", fname);
    			
    			//if statement w/ for loop inside of it
    			//go through each char, if \0 before . append ".txt" to the file
    			//else just open it
    			
    			filename = fopen(fname, "r"); //filename is just the handle to that file. have to go through filename for IO operation
    			
    			if (filename == NULL)
    				{
    					printf("Please enter a valid file name.\n");
    				}
    			else	
    				{
    					printf("File was successfully opened!\n");
    					n = 1;
    				}
    		}
    		//printf("%s\n", fname);
    		//
    		//while loop used to find the overall length of the file 
    		while (fscanf(filename, "%c\n", &temp) != EOF  ) //fscanf wants the address to store the character "&temp" not just "temp"
    			{
    				x++;
    			}
    			
    		//
    		//close and reopen file to move flag-bit to beginning of file
    		fclose(filename);	
    		filename = fopen(fname, "r");
    		
    		//allocate memory in master array based on file length (int x earlier)
    		char letters = (char *)malloc(x * sizeof(char));
    		
    		//read each character into array
    		//create filename_out.txt
    		//bubble sort
    		//write sorted array to file
    				
    		fclose(filename);
    	free(fname);
    	return(0);
    	
    }

    haha! it worked! thanks dude. also, sorry about the ** before letters. i realized that shortly after posting. i saw it in an example my teacher posted but it was for a totally different situation.

    im assuming i'd just need
    Code:
    //allocate memory in master array based on file length (int x earlier)
    char letters = (char *)malloc(x * sizeof(char));
    I could just do char letters[] but my teacher specifically said no brackets :/


    hopefully this is a little easier to read haha.
    "Life is not a journey with the intent on arriving at the finish line in a pretty and well preserved body. But rather to skid in broadside, totally worn out, thoroughly used up and loudly proclaiming, "Wow! What a ride!" -Anonymous
    Halo! || Diablo 2 LOD Modding || OLGA's BACK!
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by ChokolAwt
    also, sorry about the ** before letters. i realized that shortly after posting. i saw it in an example my teacher posted but it was for a totally different situation.

    im assuming i'd just need
    Code:
    //allocate memory in master array based on file length (int x earlier)
    char letters = (char *)malloc(x * sizeof(char));
    I could just do char letters[] but my teacher specifically said no brackets :/
    Glad you were able to make it work and even more glad that you realized that there was a problem to solve. Far better attitude than many we get here -- and, yes, I can see that you've been active in other forums here ... Java?

    But, you got it right to begin with by declaring letters as char** . It just probably doesn't make much sense since Java doesn't allow pointers (it's that "AWT" in your name that says "Java" to me). In most usages, an array name is equivalent to a pointer, so char* and char[] can be used interchangeably ... most of the time (you'll learn where it doesn't apply). And since you can have pointers to pointers to pointers, etc, you can also, much of the time, use multiple levels of indirection (what happens every time you use pointers) to indicate that you're working with extra dimensions of multi-dimensional arrays. Not always (especially when the size of those dimensions need to be known), but this is one case where it works.

    Of course, that's because I interpreted your problem as being to create an array of strings. If you are instead to create a single string, then it will be a bit different.

    If you are to create an array of strings, then do declare letters as char** . That's the same as char*[], an array of char* . That is why you will malloc the elements of the first array, the empty rows, as being of type char* , so that each element will be a char*, a pointer to a char[]. With pointers, you have referencing, adding levels of indirection, and dereferencing, working your way back up those levels -- those terms will arise.

    But if you are to create a single string, then letters needs to be a char*, which is to say a char[]. Just one less level of indirection. Just remember when you're creating a single string that you need to make room for one more character, the null-terminator, which marks the end of the string.

    Null-terminator. There are many different schemes for storing different data types. BASIC and Turbo Pascal would store strings in such a way that the very first byte contained the length of the string, so no string could ever be more than 255 characters long. C took a different approach in which there was no arbitrary limit to the length of a string. C's approach is to just give you the starting point of the string (that's the char* pointer or array name, which is the same thing) and then mark the end of the string with a special character, the null-terminator. So every single char array that contains a C-style string must be long enough to hold the longest possible string, plus one more for the null-terminator. I don't know whether you already knew all that, but you do need to know it in C.

    So then, just what is it that you need to do?

    [warte mal, warte mal ... ]

    Originally Posted by ChokolAwt
    also, as a little extra, i wanted to include a portion that would recognize if the user inputted filename was missing the '.txt' at the end of it and add it if it wasn't there. any pointers on that?
    C is a lean and mean language, but it does come with a Standard C Library. string.h contains several functions for working with C-style strings. strchr should give you the position in the string that contains a '.', though you could write a for-loop that will go through the string until it finds a '.' . In either case, you could then step through the string for the rest the extension. If it's not there, then you could contatenate a ".txt" onto the filename string, but as the destination string it will need to be large enough to accommodate that ".txt", along with one more for the null-terminator.
  8. #5
  9. The bad and the ugly...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2007
    Location
    Oz... No??? Neverland then?
    Posts
    142
    Rep Power
    0
    Code:
    //allocate memory in master array based on file length (int x earlier)
    char letters = (char *)malloc(x * sizeof(char));
    why doesn't this line compile? it keeps telling me syntax error, missing ';' before 'type'?


    i used it earlier in my code and it worked fine haha
    Code:
    //allocate memory for size of filename (char = 1 bit)
    fname = (char *)malloc(MAXCHAR * sizeof(char));

    EDIT: and yes, i made this account several years ago when I was in computer science and AP computer science in high school. java popped my cherry :D I just remembered I had an account here last night haha.
    Last edited by ChokolAwt; September 1st, 2012 at 09:55 AM.
    "Life is not a journey with the intent on arriving at the finish line in a pretty and well preserved body. But rather to skid in broadside, totally worn out, thoroughly used up and loudly proclaiming, "Wow! What a ride!" -Anonymous
    Halo! || Diablo 2 LOD Modding || OLGA's BACK!
  10. #6
  11. The bad and the ugly...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2007
    Location
    Oz... No??? Neverland then?
    Posts
    142
    Rep Power
    0
    ah got it!
    i needed to declare it first,
    Code:
    char *letters;
    before i could allocate memory for it. I guess i just figured I could declare it and the memory in the same command. I guess C wont let you do that haha.
    "Life is not a journey with the intent on arriving at the finish line in a pretty and well preserved body. But rather to skid in broadside, totally worn out, thoroughly used up and loudly proclaiming, "Wow! What a ride!" -Anonymous
    Halo! || Diablo 2 LOD Modding || OLGA's BACK!
  12. #7
  13. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    One of the rules of C is that you need to perform all declarations before the first line of executable code. You can initialize them with constant values (ie, values known at compile time), but not with functions which would be executable. So you might have been able to do it if it was the last variable declared, but I'm not sure since I'd never try that in C.

    However, you can do what you tried in C++ and apparently also in the new 1999 C standard known as C99.
  14. #8
  15. The bad and the ugly...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2007
    Location
    Oz... No??? Neverland then?
    Posts
    142
    Rep Power
    0
    Originally Posted by dwise1_aol
    One of the rules of C is that you need to perform all declarations before the first line of executable code. You can initialize them with constant values (ie, values known at compile time), but not with functions which would be executable. So you might have been able to do it if it was the last variable declared, but I'm not sure since I'd never try that in C.

    However, you can do what you tried in C++ and apparently also in the new 1999 C standard known as C99.
    interesting. i knew you could do it in C++, but again my knowledge of even that language is limited. so when my C++ engineering class turned out to be a C based class i panicked a little haha.

    its true you can do that in java too correct?
    "Life is not a journey with the intent on arriving at the finish line in a pretty and well preserved body. But rather to skid in broadside, totally worn out, thoroughly used up and loudly proclaiming, "Wow! What a ride!" -Anonymous
    Halo! || Diablo 2 LOD Modding || OLGA's BACK!
  16. #9
  17. The bad and the ugly...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2007
    Location
    Oz... No??? Neverland then?
    Posts
    142
    Rep Power
    0

    syntax error in for() loop


    Code:
    for (c; c < x; c++)
         {
    	*letters = fscanf(filename, %c\n", &temp);
         }
    im trying to read a line in a file and store it into a previously declared array (letters). the file has an unknown number of lines with 1 letter on each line.

    Code:
    letters = (char *)malloc(x * sizeof(char));
    i used malloc to decide how much memory to set aside for the array using the variable x, which is the number of lines in the file.


    how come i cant use that syntax for the for() loop? how am i supposed to navigate my way around that since the point at which to terminate the for loop isn't known at compile-time.

    thanks
    ~Tim
    "Life is not a journey with the intent on arriving at the finish line in a pretty and well preserved body. But rather to skid in broadside, totally worn out, thoroughly used up and loudly proclaiming, "Wow! What a ride!" -Anonymous
    Halo! || Diablo 2 LOD Modding || OLGA's BACK!
  18. #10
  19. The bad and the ugly...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2007
    Location
    Oz... No??? Neverland then?
    Posts
    142
    Rep Power
    0
    In C89, you are only allowed to declare variables at the beginning of a function. You are simply not allowed to declare variables elsewhere in a function, including in the initialization part of a for statement. That's why the second syntax works and the first fails.
    So i figured out my answer... i guess it's more of a workaround I'm looking for. I could use a while loop
    Code:
    while (fscanf(filename, "%c\n", &temp) != EOF  ) //fscanf wants the address to store the character "&temp" not just "temp"
    			{
    				something goes here
    			}
    but i wouldn't have a counter to know which point in the array i am at. grrrrrrr
    "Life is not a journey with the intent on arriving at the finish line in a pretty and well preserved body. But rather to skid in broadside, totally worn out, thoroughly used up and loudly proclaiming, "Wow! What a ride!" -Anonymous
    Halo! || Diablo 2 LOD Modding || OLGA's BACK!
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    156
    Rep Power
    33
    plain C89 follows :)

    [code=c]#include <stdio.h>
    #include <stdlib.h>

    int main(void) {
    char *letter;
    int c = 0, x = 26;

    letter = malloc(x + 1); /* for the NUL terminator */
    if (!letter) exit(EXIT_FAILURE);
    for (; c < x; c++) {
    letter[c] = 'A' + c; /* fails in EBCDIC computers */
    }
    letter[c] = 0;
    printf("%s\n", letter);
    free(letter);
    return 0;
    }[/code]
  22. #12
  23. The bad and the ugly...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2007
    Location
    Oz... No??? Neverland then?
    Posts
    142
    Rep Power
    0
    Originally Posted by bdb
    plain C89 follows :)

    [code=c]#include <stdio.h>
    for (; c < x; c++) {
    [/code]
    i get a syntax error when it hits 'x'...
    "Life is not a journey with the intent on arriving at the finish line in a pretty and well preserved body. But rather to skid in broadside, totally worn out, thoroughly used up and loudly proclaiming, "Wow! What a ride!" -Anonymous
    Halo! || Diablo 2 LOD Modding || OLGA's BACK!
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    156
    Rep Power
    33
    Originally Posted by ChokolAwt
    i get a syntax error when it hits 'x'...
    Maybe you didn't copy and paste the code correctly.
    The ideone.com's interface works without errors: http://ideone.com/lIesD
  26. #14
  27. The bad and the ugly...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2007
    Location
    Oz... No??? Neverland then?
    Posts
    142
    Rep Power
    0
    Originally Posted by bdb
    Maybe you didn't copy and paste the code correctly.
    The ideone.com's interface works without errors: http://ideone.com/lIesD

    at the top of the page: "language: C99 strict (gcc-4.3.4)"

    this doesn't help me :(

    what if i just used a while loop?
    Code:
    while (fscanf(filename, "%c\n", &temp) != EOF)
    	{
    		*letters + c = temp;
    		c++;
    	}
    im getting an error on the *letters + c line... but maybe i'm getting closer?


    got it.
    Code:
    *(letters + c) = temp;
    i couldn't add the integer to the whole array lol, i just needed to add the integer to the memory location. now to double check that it read in the file correctly.
    Last edited by ChokolAwt; September 3rd, 2012 at 05:37 PM.
    "Life is not a journey with the intent on arriving at the finish line in a pretty and well preserved body. But rather to skid in broadside, totally worn out, thoroughly used up and loudly proclaiming, "Wow! What a ride!" -Anonymous
    Halo! || Diablo 2 LOD Modding || OLGA's BACK!
  28. #15
  29. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Try *(letters + c)

    That provides the compiler with an lvalue (from "left value"), which must resolve to a location in which to store thervalue. It performs pointer arithmetic to the address and then dereferences it. In your original, first you dereferenced letters which got you the value stored there and then added c to it, but that made the expression an invalid one for being an lvalue.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo