Solved

I am looking for a function which can move out the spaces from the front of a string

Posted on 2000-04-12
18
160 Views
Last Modified: 2010-04-15
I use fgets to read lines from a file. And I am going to use the first char as a mark. But the first char of many lines is not a char but space or tab. I want to trim out the spaces. Which function can do this in C?
0
Comment
Question by:chenwei
  • 6
  • 6
  • 2
  • +4
18 Comments
 
LVL 22

Expert Comment

by:cookre
ID: 2707995
Use scanf with a leading blank in the format before the %s.  This says you want to start storing into the specified string with the first non-white space character .
0
 

Author Comment

by:chenwei
ID: 2708083
Thanks for your help first. Maybe I haven't explained my question exactly. There are sometimes not only one space but several spaces before a string as follow:
"
! here is the head
   # here is the format

      110  ..................
      150  ................
    2100  ................
 340000  .................

  ...
  ...
"

Can I use the method you said to overcome it? Besides, I will check if the first char is neither '!' nor '#' ,that means the data is comimg.

0
 
LVL 3

Expert Comment

by:marcjb
ID: 2708133
You could also write a function that trims the whitespace off the beginning to a string.  The following function trims leading space and returns the length of the new string.

int stringTrim(char *s)
{
int len = strlen(s);
int i;

for ( i = 0; isspace(s[i]); i++ )
    ;
len -= i;
if ( i )
    memmove(s, s + i, len + 1); /* Grab the NULL terminator */

return len; /* This is the new strlen */
} /* stringTrim */
0
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 

Author Comment

by:chenwei
ID: 2708140
Thanks for your help first. Maybe I haven't explained my question exactly. There are sometimes not only one space but several spaces before a string as follow:
"
! here is the head
   # here is the format

      110  ..................
      150  ................
    2100  ................
 340000  .................

  ...
  ...
"

Can I use the method you said to overcome it? Besides, I will check if the first char is neither '!' nor '#' ,that means the data is comimg.

0
 
LVL 16

Expert Comment

by:imladris
ID: 2708240
How about using strspn:

#include <string.h>

size_t strspn(char *string1,char *string2);

Returns the position of the first non-matching character in string1.


So for example if fgets returns its result in line:

int i;
i=strspn(line," \t");

then i, in this example, will be the index of the first nonblank nontab character.
0
 
LVL 22

Expert Comment

by:cookre
ID: 2708296
scanf(" %s",LineIn)

will strip ALL leading whitespace from the line.  You'll end up seeing those sample lines as:


! here is the head
# here is the format
110  ..................
150  ................
2100  ................
340000  .................
0
 

Expert Comment

by:babashri
ID: 2711558
for the file fscanf is used as follows

 
      FILE *fp;
      char str[100];
      fp = fopen("test.txt","r");
      while(!feof(fp))
      {
            fscanf(fp,"%s",str);
            printf("%s",str);
                // str is having no leading and trailing spaces
      }
0
 

Expert Comment

by:Namita
ID: 2711737
I think so better to  use fgetc().
0
 
LVL 8

Expert Comment

by:stochastic
ID: 2714856
cookre,

Your solution is nice - it trims all leading white spaces, but won't it trim everything AFTER the first word too? This could cause a problem if chenwei's data lines contain embedded spaces.

For instance, if chenwei's first data line is
   12345 AndSomeData SomeMoreData
then your solution would make LineIn
as only "12345"; it would drop the rest of the line because of the space immediately following "12345". Won't it?

Imladris's solution
-------------------
Imladris's solution is more general, I think. But s/he didn't explain what to do after getting the index. It may be obvious to most C programmers, but not to a beginner. So please permit me to clarify.

a. Note that in the line
i=strspn(line," \t");
there is a space _and_ a tab (\t). Don't miss the space. It is not visually obvious that there is a space there.

b. chenwei, once you get an index i, you should use (line+i) instead of line in further processing. (line+i) will be a pointer that will point to the first non-space character, and therefore will in effect, represent a null-terminated string that starts from first non-space character and ends at the null character (so takes the whole line)

my own suggestion
-----------------
chenwei, since you said you were using fgets, let me proceed on that line.

Let me assume that you read the line into a buffer called InputLine, with a statement somewhat like
fgets(InputLine, 256, filepointer);

What I would suggest you do is this:

a. Declare a char * pointer at the start of the function, say
char *C;

b. to 'trim' the InputLine by removing leading spaces, just write a statements at an appropriate place;

C = InputLine;
while (*C == ' ' || *C == '\t') C++;

c. Now, just use C in place of InputLine.

Hope you understand this logic. It is simple, and it will do what you need in a very general way.

By the way, instead of
while (*C == ' ' || *C == '\t') C++;

you could have said

while (isspace(*C)) C++;

but that would involve explaining isspace() macro or function, which may not exist on all compilers.

Hope this helps

- stochastic
0
 
LVL 8

Expert Comment

by:stochastic
ID: 2714868
Sorry marcjb,

I didn't see your posting earlier. You had already suggested what I did. Still, I think it may not be necessary to copy the remaining text backward in the buffer like you did (whether this is needed or not depends on what exactly chenwei wants to do; but I feel for most purposes, one may be able to do without it). Also, if chenwei takes your suggestion, you could explain what happens in your code, in greater detail for the asker's benefit.

Let me illustrate a bit further.

Imagine that InputLine contained
"   12345 AndSomeData SomeMoreData"

With marcjb's answer,
InputLine becomes "12345 AndSomeData SomeMoreData"

with my answer, InputLine stays the same, but C becomes "12345 AndSomeData SomeMoreData"; without the need to move any data around. Also, C is merely a pointer to the same actual data storage; so no new data storage needs to be allocated.

I hope I have added at least _some_ value with the explanation.

- stochastic
0
 
LVL 8

Expert Comment

by:stochastic
ID: 2714925
Sorry marcjb,

I didn't see your posting earlier. You had already suggested what I did. Still, I think it may not be necessary to copy the remaining text backward in the buffer like you did (whether this is needed or not depends on what exactly chenwei wants to do; but I feel for most purposes, one may be able to do without it). Also, if chenwei takes your suggestion, you could explain what happens in your code, in greater detail for the asker's benefit.

Let me illustrate a bit further.

Imagine that InputLine contained
"   12345 AndSomeData SomeMoreData"

With marcjb's answer,
InputLine becomes "12345 AndSomeData SomeMoreData"

with my answer, InputLine stays the same, but C becomes "12345 AndSomeData SomeMoreData"; without the need to move any data around. Also, C is merely a pointer to the same actual data storage; so no new data storage needs to be allocated.

I hope I have added at least _some_ value with the explanation.

- stochastic
0
 

Author Comment

by:chenwei
ID: 2714986
Thanks for the tips and help from all sites. The following is my code:
***************************
stream=fopen("myfile","r");
      
while(!feof(stream))
{
  fgets( line, 100, stream);
  if(strlen(line)!=0)
  {
     sscanf(line, "%s", trim_line );
     if((trim_line[0]!='!') && (trim_line[0]!='#'))
     {
         sscanf(line, "%d %lf %lf \n", &a,&b,&c);
     }
  }
}
***************************

0
 
LVL 8

Expert Comment

by:stochastic
ID: 2715214
chenwei,

I edited your code as follows:
you may have declared trim_line as
char trim_line[100]; or something similar. Please change that to
char *trim_line;


************
stream=fopen("myfile","r");

while(!feof(stream))
{
  fgets( line, 100, stream);
  if(strlen(line)!=0)
  {
     trim_line = line;
     while (*trim_line == ' ' || *trim_line == '\t') trim_line++;
     if((trim_line[0]!='!') && (trim_line[0]!='#'))
     {
         sscanf(line, "%d %lf %lf \n", &a,&b,&c);
     }
  }
}
***************************
this should work fine, except that I would suggest that the line
     if((trim_line[0]!='!') && (trim_line[0]!='#'))
should be changed to
     if(*trim_line!='!' && *trim_line!='#')

Hope this helps
- stochastic



0
 

Author Comment

by:chenwei
ID: 2715287
Thanks for your help, stochastic. But as I run the program till
sscanf(line, "%d %lf %lf \n", &a,&b,&c);

It shows a runtime error. Why?
0
 
LVL 8

Expert Comment

by:stochastic
ID: 2715323
chenwei,

Sorry,
sscanf(line, "%d %lf %lf \n", &a,&b,&c);
should actually be
sscanf(trim_line, "%d %lf %lf \n", &a,&b,&c);
     
I overlooked that.

If that doesn't fix it ... hmmm.    
What is the runtime error? How about posting the full program and a couple of lines of the sample input file? It would be hard to tell otherwise.

Hope you have declared a,b,c correctly.
int a;
double b, c;
is what I guess from your sscanf statement.


- stochastic


0
 

Author Comment

by:chenwei
ID: 2715353
I've solved the problem. There is a mistyping in my program.

Please lock my question so I can give you the points.

Thanks!
0
 
LVL 8

Accepted Solution

by:
stochastic earned 20 total points
ID: 2715371
You can grant the points by simply choosing "Accept as Answer" on my comment. I don't have to lock the question by putting a comment as an answer.

- stochastic
0
 

Author Comment

by:chenwei
ID: 2715379
I've solved the problem. There is a mistyping in my program.

Please lock my question so I can give you the points.

Thanks!
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

831 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