Thread: printing a string on a char matrix

  1. #1
    Registered User
    Join Date
    Apr 2014
    Posts
    26

    printing a string on a char matrix

    So I have an array of char called s.

    This array has many words inside, each one separated by '\0'.

    The words are sorted by length (from bigger to smaller).

    I have have a char matrix with random things inside (it was not initialized) caled mat.

    I want to copy the first word from the array s to the matrix mat.


    Code:
        int nlin, ncol; /*number of lines and collumns.*/
        int c,l,a,q;
        char mat [1000][1000];    
        char s[1000];
    
    /*insert first word from s on mat*/
    
        for(l=0,c=0,a=0,q=0;(strlen(s)<=(ncol*nlin))&&(s[a]!='\0');q++){
               
     /*the word from s is printed on mat until s[a] reaches the end of the word. If the word has more chars in number then spaces on the matrix, this for is just ignored.*/
            
    
               for(;((c<ncol-q-1)&&(s[a]!='\0'));a++,c++){
               
     /*inside this for, we print the word from the array s through the matrix's first line's columns from first to last.*/ 
    
                     mat[l][c]=s[a];
                }
    
                for(;((l<nlin-q-1)&&(s[a]!='\0'));a++,l++){
                
    /*inside this for, we print the word from the array s through the matrix's last coumns' lines from first to last.*/
    
                     mat[l][c]=s[a];
                 }
        
                  for(;((c>q)&&(s[a]!='\0'));a++,c--){
                       
     /*inside this for, we print the word from the array s through the matrix's last line's columns from last to first.*/
    
                       mat[l][c]=s[a];
                   } 
    
                   for(;((l>q)&&(s[a]!='\0'));a++,l--){
                
    /*inside this for, we print the word from the array s through the matrix's first column's lines from last to first.*/
    
                       mat[l][c]=s[a];
                }
        }
    
        if (s[a]!='\0') {printf("Impossible to constroy matrix\n");return 0;}
    
    
    
    /*print matrix*/
    
        for (l=0;l<nlin;l++) {
            for(c=0;c<ncol;c++) {
                printf("%c",mat[l][c]);
            }
            printf("\n");
        }
        return 0;
    }
    I can't see where this is wrong, but, when i test it, it clearly is not right. for example, if the input is 3 lines and 3 columns for the matrix and the word is crate, the output is :

    cra
    t
    e


    but it should be:

    cra
    t
    e

    Where did i go wrong?

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Well, given that your actual output looks exactly like your expected output, then I would say nothing is wrong.

    Some issues I see, however:

    • You didn't provide us a complete, compileable example, with sample input that causes your problem, so it's hard for us to test and find your issue.
    • You use crappy variable names like c, l, a and q, that make it difficult for us to figure out exactly what you're trying to do. Try using names like curr_line and curr_col to help clear things up.
    • All of the inner for loops have the same comment and body, which also makes it hard to figure out what you're trying to do. Plus, the conditions are different, so they likely each do something screwy..
    • Also, you use magic numbers (1000) that should be replaced with name constants, like MAX_SIZE.
    • nlin, ncol, c, l, a and q all have invalid values to start. You compare strlen(s) to ncol*nlin. You should get a warning if you turn up your compiler warning to the max level.
    • You separate words in s based on the '\0' char. But how do you know the difference between a valid string of "some\0stuff\0and\0more\0words" vs. "two\0words\0as!#&R&*@#P(Uwliefjpijf80o2489fouhfeo hewf\0" where there is a bunch of garbage in s, followed by a null char?
    • You don't say how you want to copy it into mat. Presumably mat[0] contains the first word, mat[1] the second, etc, but you're not clear.


    That should give you something to work on for now.

  3. #3
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Is all you are wanting to do is copy a single word at a time from array s into a new row of mat? That's what I got from your explanation, but the number of for loops confused me as to what you were doing.

  4. #4
    Registered User
    Join Date
    Apr 2014
    Posts
    26
    the c and l represent columns and lines. Itś with those variables that we are going to "walk" the matrix.

    the variable a is just used to walk the string s and q is used to not have words being printed on the same place that others were printed before. The idea is to print the word on a spiral.

    its ok if s has more words inside because for now i only care about the first word, anything after the first '\0' does not have importance.

    the inputi is: number of columns and number of lines of the matrix and the word.

    I want the word to be printed on the matrix and to have all letters one after the other. For example, I want to have knife and not fekni. With this in mind, if the word has more letters then the columns of the matrix i will have to continue printing on the last column so that the letters are followed. that is why i have so many fors they continue to print the word in a spiral, that's the idea

    and im sorry, i wrote the output wrong.

    It is outputing the following matrix with the example crate and 3 lines and 3 columns (the input is number of lines, number o columns and word):

    Code:
    cra
    t
    e
    but the expected output would be:

    Code:
    cra
      t
      e

    I didnt write here my whole code because it is very big this is just a portion of it. I just wanted to explain my strategy, i explained on this post and on the comentaries of the code. I want to know if what is wrong is my strategy. Do you guys think this way of printing the word is not going to work for some reason? (it is in fact not working, but is it because my strategy is bad?) Or should I stick to this and try to better it? If it's a good strategy can you point me on the right direction to notice what's is wrong?

    And what is wrong with comparing strlen(s) with ncol*nlin? they are both integers right?

    thanks in advance.

  5. #5
    Registered User
    Join Date
    Apr 2014
    Posts
    26
    Quote Originally Posted by anduril462 View Post

    • All of the inner for loops have the same comment and body, which also makes it hard to figure out what you're trying to do. Plus, the conditions are different, so they likely each do something screwy..
    • You separate words in s based on the '\0' char. But how do you know the difference between a valid string of "some\0stuff\0and\0more\0words" vs. "two\0words\0as!#&R&*@#P(Uwliefjpijf80o2489fouhfeo hewf\0" where there is a bunch of garbage in s, followed by a null char?
    • You don't say how you want to copy it into mat. Presumably mat[0] contains the first word, mat[1] the second, etc, but you're not clear.

    The comentaries on the inner loops are diferent. They start with the same words but say diferent things in the end.
    just look at s like a simple string, what goes after the first '\0' has no importance for now.

    Also I want to print the word in spiral as I mentioned on my last post and as you can see on my posts so its not as you said, not a word for each line, I want to insert a single word on a spiral. By spiral I mean this:

    take the word, howareyoutoday and a matrix of 5 lines and 6 columns as an example:

    Code:
    
      howare
           y
           o
           u
       yadot
    I hope I was clear enough, if anyone didn't understand please ask.
    Last edited by Lired; 05-28-2014 at 06:23 AM.

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    And what is wrong with comparing strlen(s) with ncol*nlin? they are both integers right?
    Not really, strlen() returns a size_t, an implementation defined unsigned type, while both ncol and nlin are signed ints. Since an unsigned int can hold larger values than a signed int you need to be careful when you try to compare values with these different types.

    Jim

  7. #7
    Registered User
    Join Date
    Apr 2014
    Posts
    26
    thank you Jim, ok I will change that, but the main problem still persists so however can help me on the rest I will be gratefull too

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    can help me on the rest I will be gratefull too
    Possibly but I suggest you re-read post #8 and implement some of the suggested changes. Your variable names for instance, you should use descriptive variable names if you want someone other than yourself to read your program. Also as stated posting a small complete program that illustrates the problem would help. Then we could compile and run the code and maybe see for ourselves what is happening.

    Jim

  9. #9
    Registered User
    Join Date
    Apr 2014
    Posts
    26
    Well I have been thinking and i think i now understand what's happening with my program.
    It is outputing


    Code:
    crat
    e

    when it should output:

    Code:
    crat
       e

    but i did now some printf to know how are the values of l (lines) and c(columns) changing during each iteration of each for. It shows that every char is being stored on the right place on the matrix, but when i see the output on the terminal it is like it ignored the spaces before, on the crate exemple, before e. If this is right then it works for every case, I think it just ignores these spaces. It's the only logical explanation.

    So the question I ask now is, is it possible that the terminal would ignores spaces like this?

  10. #10
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    No the console will print whatever you tell it to print. The problem is probably that you're not properly inserting the characters into the mat array properly. Also don't forget the end of a "word" is a whitespace character. So let's look at your first for loop:

    Code:
     for(l=0,c=0,a=0,q=0;(strlen(s)<=(ncol*nlin))&&(s[a]!='\0');q++){
    If this string is "This is my large string" the strlen() would yield 23 and you should never see a '\0' character. Remember the '\0' character is the end of the string character. Also IMO you're really complicating things by inserting all those initializes in the for loop. Put the "extra" initializations elsewhere. Keep your loop simple. All the interactions from one loop to the next in this series of loops is confusing and is probably the source of the problem again IMO. But without a complete program I'm just guessing.

    And you probably should be sure to initialize mat[][] to some known value before you start, and really a size of 1000 is probably a bit much. Most "English words" are much much smaller.

    Jim

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Those examples of "spiral printing" now make it clear what you are trying to do.

    Sorry, I was a bit tired last night and missed the difference in the comments. I should note, however, that you can drop the "inside this for" part, and technically you are not printing a word, but copying a single character from s to mat. Just a suggestion, but I think it would make your code much clearer if the inner for loops were something like this:
    Code:
    /* copy letters right-to-left across the top of mat */
    for (col = start_col; col < end_col; col++) {
    }
    /* copy letters down the right side of mat */
    /* copy letters left-to-right across the bottom of mat */
    /* copy letters up the left side of mat */
    Look at my for loop, notice how simple it is to understand, col increments from a start_col value to an end_col. The other loops should look similar, substituting start_row and end_row, and incrementing or decrementing col/row as appropriate.

    That only leave one thing: determining start_col, end_col, start_row and end_row before each for loop. Work out several examples on paper, with different size matrices and different length strings/words. Notice what values you begin with for col, row, start_col, end_col, start_row and end_row, and how they change as you move onto the next for loop. Once you understand how they change each time, you just have to fill in a couple lines before each of the 4 for loops.

    The problem with comparing strlen(s) to ncol*nlin is that, as I sais before, ncol and nlin don't have valid values. You declare them, but never give them a value, so you are comparing strlen(s) with garbage. That technically results in undefined behavior meaning anything (or nothing) could happen, but in practice it will likely just use garbage values.

    Calling strlen each time through the loop is inefficient -- you should use a temp variable. Also, the strlen check is a loop invariant -- it never changes it value between iterations. That means you don't even need it in the loop. I would check it once before hand to see if the word will fit in the matrix. If not, bail out, if it does, carry on.

    EDIT: I just realized you use the term "line" instead of "row" -- either is fine, just be consistent.

  12. #12
    Registered User
    Join Date
    Apr 2014
    Posts
    26
    Thank you anduril, i will take your advice. And i now can see what the problem was so i shouln't have any more trouble with this code.

    Thanks to all that helped.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help with searching a string on a char matrix.
    By Lired in forum C Programming
    Replies: 6
    Last Post: 04-13-2014, 08:05 AM
  2. reading a matrix and printing out the matrix
    By Lina_inverse in forum C Programming
    Replies: 9
    Last Post: 10-23-2012, 04:09 PM
  3. Printing out a matrix of characters
    By Y2R in forum C Programming
    Replies: 7
    Last Post: 04-14-2012, 11:23 PM
  4. Replies: 11
    Last Post: 06-16-2011, 11:59 AM
  5. Printing a Matrix?
    By Nebbuchadnezzar in forum C++ Programming
    Replies: 4
    Last Post: 07-08-2005, 08:11 PM

Tags for this Thread