Thread: recoding strings

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    90

    recoding strings

    Hello,
    I have data written on DOS on my specific codepage (852).
    If I want to read this data in windows I must recode strings to replace non english characters and I do this successfully with VB program.

    Now I want to replace those characters, readed from file, with C and I can't do this with following code.
    Probably because I am total C newbie.

    Code:
    	int i;
    	char* ps = mystring;
    	for (i = 0; i <= sizeof(mystring); i++)
                 {
    	 switch(*ps){
                   case 230: *ps=208;
                   break;
                   case 209: *ps=230;
                   break;
                   .
                   .
                   .      
                   }
                 }
    I get error: case label value exceeds maximum value for type
    After some digging I found that char values can be to 127 what causes those error.
    Shown part of program change characters well when they are under ASCII 127.
    What should I do to be able to change ASCII characters in range 0-255?

    Of course, I would like to recode again before writing data back to disk so my DOS program would be able to read it. But this is the same problem as described above.

    For more information here is my "lookup" table in form:
    char_from, char_to, ASCII_from, ASCII_to

    ć Đ 230 208
    Ń ć 209 230
    Đ Ć 208 198
    † Ž 134 142
    ¬ č 172 232
    Ź ž 143 158
    ¦ š 166 154
    ź Š 159 138
    § Č 167 200
    ç đ 231 240

    Thanks in advance, nime.

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    It sounds like you're asking your compiler to error out there with -Werror, because the code is not invalid. However, it is a useful warning. The problem is that char on your system is signed. Thus anything 128-255 will (reasonably assuming an 8-bit char) be represented as a negative value. The simplest fix would be to cast the controlling expression of your switch to an unsigned char.

  3. #3
    Registered User
    Join Date
    Mar 2010
    Posts
    90
    Hm, cas,
    that sounds more complicated than in VB.
    I understand what you tell but after few tryes I cant get it to work.
    Can you please show me where and how to cast with a little example code?

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Code:
    switch((unsigned char)*ps)

  5. #5
    Registered User
    Join Date
    Mar 2010
    Posts
    90
    Thanks cas, you are guru!

    In meantime, when I dont know C enough, I found one more "interesting" solution "by hand"

    Code:
            case 127-209: *ps=127-208;
             break;
            case 127-208: *ps=127-240;
             break;
             .
             .
             .
    But I can't try if this works at the moment.
    Anyway, one solution will surely be good I belive.

    Thanks again, nime.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by nime View Post
    Thanks cas, you are guru!

    In meantime, when I dont know C enough, I found one more "interesting" solution "by hand"

    Code:
            case 127-209: *ps=127-208;
             break;
            case 127-208: *ps=127-240;
             break;
             .
             .
             .
    But I can't try if this works at the moment.
    Anyway, one solution will surely be good I belive.

    Thanks again, nime.
    switch doesn't work with hypenated values, ranges or sets. It needs and explicit constant.

  7. #7
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    replace non-ascii char with what?
    you can just use isascii() from ctype.h.
    isascii()
    checks whether c is a 7-bit unsigned char value that fits into
    the ASCII character set.
    Try to read man pages yourself.

    Edit: arhh. Ok, I didn't see your table.
    You can use table.
    Code:
    unsigned char trans_tab[ ] = { 
       ......
      [230-127] = 208, ..       
    };
    unsigned char ch = (unsigned char) *p;
    if( !ascii( ch ) ) 
       ch = trans_tab[ ch - 127];
    Since ascii chars are not going to change,rite?
    Then you just need 255-127 elements in your table.
    Last edited by Bayint Naung; 01-24-2011 at 12:47 AM.

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    90
    Thank you guys.
    Cas's solution works just excellent. Properly and very fast.
    I can read my data now in notepad just well
    Code:
    switch((unsigned char)*ps)
    But when we're here one more simple question about C.

    I would like to refresh my progressbar after every 1000 readed records.
    In VB I do like this:
    Code:
     If (count/1000)=Fix(count/1000)
        ' count is divided by 1000 without reminder 
        ' time to refresh!
        end if
    
    How to do this with C?

  9. #9
    Registered User
    Join Date
    Mar 2010
    Posts
    90
    I found!
    I someone would need it here is sample:

    Code:
    // 'o' is int declared before
    
    if ((float)o/1000 == o/1000)
         printf("%d \n", o/1000);

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by CommonTater View Post
    switch doesn't work with hypenated values, ranges or sets. It needs and explicit constant.
    I'm pretty sure (given the "overlap") that OP is not intending "ranges" so much as "subtraction".

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by tabstop View Post
    I'm pretty sure (given the "overlap") that OP is not intending "ranges" so much as "subtraction".
    He should still be getting at least a warning that "case requires constant"... which is what I got when I tried it in PellesC.

  12. #12
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    I compiled with gcc -Wall and get no warnings.
    I think const op const should give const

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by CommonTater View Post
    He should still be getting at least a warning that "case requires constant"... which is what I got when I tried it in PellesC.
    That's an error in PellesC. switch is obliged to accept constant expressions, at least in C99 (I don't have the C89 standard).

  14. #14
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by tabstop View Post
    That's an error in PellesC. switch is obliged to accept constant expressions, at least in C99 (I don't have the C89 standard).
    If I do it with the actual numbers... like it was posted... no error.... try it with variables (which is where I thought it was heading) and it complains.

    Pelles C is C-99.

  15. #15
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    case 10 + 3 :
    should be OK.
    while case n: //where n is variable
    the compiler will give error.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strings Program
    By limergal in forum C++ Programming
    Replies: 4
    Last Post: 12-02-2006, 03:24 PM
  2. Programming using strings
    By jlu0418 in forum C++ Programming
    Replies: 5
    Last Post: 11-26-2006, 08:07 PM
  3. Problems with strings as key in STL maps
    By all_names_taken in forum C++ Programming
    Replies: 3
    Last Post: 01-17-2006, 11:34 AM
  4. Reading strings input by the user...
    By Cmuppet in forum C Programming
    Replies: 13
    Last Post: 07-21-2004, 06:37 AM
  5. menus and strings
    By garycastillo in forum C Programming
    Replies: 3
    Last Post: 04-29-2002, 11:23 AM