Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Replace tab, line break character function (C)

Posted on 2011-05-10
8
Medium Priority
?
565 Views
Last Modified: 2012-06-21
Experts,

I'm having trouble writing a function to replace newline and tab (\n, \r, \t) characters in C. It seems strtok doesn't accept any escaped characters.

The function prototype should look something like this with a char reference:
void removeChars( char ** input_output_char) { ... }

Can you please point me in the right direction on how to write this function?

Thanks!
0
Comment
Question by:php-newbie
  • 2
  • 2
  • 2
  • +2
8 Comments
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 35730706
Hi Newbie,

strtok accepts escaped characters just fine.  Can you show us what you're doing that looks like it's not working?

The function header should probably contain a string pointer, as well as a delimiter pointer (unless you're always going to use the same characters as separators).  The pointer to pointer reference is probably overkill.


Kent
0
 
LVL 86

Expert Comment

by:jkr
ID: 35730788
As a simple solution:
void removeChars( char* input_output_char) { // 'char**' is unnecessary

  char* p = input_output_char;

  while(*p) {

    switch(*p) {

       case '\t':
       case '\r':
       case '\n':

         *p = *(p + 1);
         break;

       default:

         break;
    }

     p++;
  }

}

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 35730896
Ooops, correction:
void removeChars( char* input_output_char) { // 'char**' is unnecessary

  char* p = input_output_char;

  while(*p) {

    switch(*p) {

       case '\t':
       case '\r':
       case '\n':

         *p = *(p + 1);

         if (!*p) return;

         break;

       default:

         break;
    }

     p++;
  }

}

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 16

Expert Comment

by:HooKooDooKu
ID: 35732258
@jkr,

Won't your function simply copy characters that follow \t,\r,\n with what comes after is, such that the oringinal string "ABC\nXYZ" becomes "ABCXXYZ"?

@newbie,

You say you want to "replace" these esc codes, but you don't say what you want to replacement with nor does your function prototype allow you to specify anything to replace them with.

If you do simply want to remove the characters then the following would remove the characters from the string "in place" as jkr tried to do.  The String "ABC\tXYZ\r123\0" becomes "ABCXYZ123\03\0" (the "3\0" being the bytes in the original string that come AFTER the NULL that now appears earlier in the string to shorten it).

Note that the 'if()' statements below are optional.  You will get a slight performance boost by including them if the original string seldom includes the charactors to remove or the charactors to remove typically appear very late in the string.
void removeChars( char* input_output_char )
{
  char* ch1 = input_output_char;
  char* ch2 = input_output_char;
  while( *ch2 )
  {
    switch( *ch2 )
    { 
      case '\t': case '\r': case '\n';
        ch2++;
        break;
      default;
        if( ch1 != ch2 )   //If statement is optional 
          *ch1++ = *ch2++;
    }
  }
  //ch2 should now be pointing to NULL as end of string ('\0')
  if( ch1 != ch2 )   //If statement is optional 
    *ch1++ = *ch2++;
}

Open in new window

0
 
LVL 16

Expert Comment

by:HooKooDooKu
ID: 35732280
Opps, the 'case' statement has a typo and ends with a semicolon (;) rather than a colon (:)
0
 
LVL 33

Accepted Solution

by:
phoffric earned 2000 total points
ID: 35733498
This program replaces \n, \r, and \t with a space and sets the start of the string to the first non-blank char.
   A
BC      XYZ123

A  BC XYZ123

Open in new window


#include <stdio.h>  
#include <string.h>  

void removeChars( char ** input_output_char) {
    char * ptrString = *input_output_char;
    char * start_of_string = *input_output_char;
    char keys[] = "\n\t\r";
    while(  (ptrString = strpbrk (ptrString,keys) ) != NULL ) {
        *ptrString = ' ';
    }
    while( *start_of_string == ' ' ) {
        ++start_of_string;
    }
    *input_output_char = start_of_string;
}

int main() {
    char str[] = "\r\n   A\r\nBC\tXYZ123";
    char * pStr = str;
    printf( "%s\n\n", pStr);
    removeChars( &pStr );
    printf( "%s\n\n", pStr);
}

Open in new window

0
 
LVL 33

Expert Comment

by:phoffric
ID: 35734374
Had to leave, so I didn't have time to explain.

The strpbrk function searches the input string, ptrString, for any char in keys (which in this case consists of your three escape chars). If it finds one of these escape chars, then it returns a pointer whose address is the location in the string of the escape char; otherwise, if the escape char is not found, then it returns NULL. Here's detailed explanation of the strpbrk function:
    http://www.cplusplus.com/reference/clibrary/cstring/strpbrk/

After finding one of the 3 escape chars in the while loop, they are overwritten with a space. The program could have called strpbrk again using the starting position of the input string, but that would not be very efficient, since we know that there are no escape chars from the start position to the overwritten location. Instead, the search begins at just one char past the overwritten escape char.

After all escape chars are replaced with a blank, the next while loop searches for the first non-blank char, and the new start_of_string is passed by via your char ** input pointer.
0
 
LVL 35

Expert Comment

by:sarabande
ID: 35739764
the strtok replaces found separators by a zero char what does terminate the current substring. so it actually 'cuts' the input buffer into pieces what makes the strtok not so suitable for your task. if you would like to replace all the \n, \r, \t by the same (single) character - say the space char - you could use the strtok nevertheless and could change the zero terminator of each substring returned by strtok by a space

  if (token != NULL)
        token[strlen(token)] = ' ';  // now the input string has a space for the separator

however that also would replace the last zero terminator of the whole input string. so you finally would need to restore that terminator by assigning a zero char at the original length index.

Sara
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

581 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question