# C Programming Question

**URL:** <https://boards.straightdope.com/t/c-programming-question/607832>\
**Category:** In My Humble Opinion\
**Created:** [December 30, 2011, 2:57pm UTC](https://boards.straightdope.com/t/c-programming-question/607832 "2011-12-30T14:57:24Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bag\_of\_Mostly\_Water](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/bag_of_mostly_water/32/1029_2.png) [@Bag\_of\_Mostly\_Water](https://boards.straightdope.com/u/Bag_of_Mostly_Water)\
**Post date:** [December 30, 2011, 2:57pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/1 "2011-12-30T14:57:24Z")

</div>

I’m writing a C program which needs to remove any trailing spaces from a string. The code I’ve proposed for this looks like this:

```auto

while ((last_char == space) && (string_length > 0))
   {
      remove_last_char;
   }

```

Another programmer I’m working with says “real” C programmers don’t use while loops. He says a better way of doing this is:

```auto

for (int i = string_length; i > 0; i--)
   {
   if (last_char == space)
      {
          remove_last_char;
      } else {
         break;
   }

```

The for loop seem convoluted and the break feels a bit like a goto in this context. The while loop seems cleaner and easier to follow.

What say the cognoscenti on the Dope?

---

<div class="post-metadata">

**Author:** ![beowulff](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/beowulff/32/542_2.png) [@beowulff](https://boards.straightdope.com/u/beowulff)\
**Post date:** [December 30, 2011, 3:11pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/2 "2011-12-30T15:11:16Z")

</div>

I’ve never heard of “real” C programmers not using while loops.  
Either way is fine.

---

<div class="post-metadata">

**Author:** ![Gagundathar](https://avatars.discourse-cdn.com/v4/letter/g/a183cd/32.png) [@Gagundathar](https://boards.straightdope.com/u/Gagundathar)\
**Post date:** [December 30, 2011, 3:14pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/3 "2011-12-30T15:14:15Z")

</div>

Your friend is mistaken.

---

<div class="post-metadata">

**Author:** ![ptr2void](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/ptr2void/32/3406_2.png) [@ptr2void](https://boards.straightdope.com/u/ptr2void)\
**Post date:** [December 30, 2011, 3:14pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/4 "2011-12-30T15:14:47Z")

</div>

> [@](#):
>
> Another programmer I’m working with says “real” C programmers don’t use while loops.

He’s full of shit. A real C programmer uses whatever loop best fits the situation.

Your example does not show enough to know if it’s a workable solution; I mean, what is _remove\_last\_char_ exactly?

```auto

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

int main() {
   char my_string[] = "This string has spaces at the end. ";
   char no_spaces[] = "This string has none.";
   char *p = &my_string[strlen(my_string) - 1];
   while (*p == ' ' && p != my_string) --p;
   *(p+1) = '\0';
   printf("%s#
", my_string);
   p = &no_spaces[strlen(no_spaces) - 1];
   while (*p == ' ' && p != no_spaces) --p;
   *(p+1) = '\0';
   printf("%s#
", no_spaces);
   return 0;
}

```

---

<div class="post-metadata">

**Author:** ![Jragon](https://avatars.discourse-cdn.com/v4/letter/j/e19b73/32.png) [@Jragon](https://boards.straightdope.com/u/Jragon)\
**Post date:** [December 30, 2011, 3:17pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/5 "2011-12-30T15:17:41Z")

</div>

```auto

for ( ; (last_char == space) && (string_length > 0) ; )
   {
      remove_last_char;
   }

```

Problem solved

😛

But seriously, use whichever is easier to read and requires the least reasoning to interpret, for and while loops are functionally equivalent, in fact, a for loop or the form

```auto

for(ASSIGNMENT ; EXPRESSION ; ASSIGNMENT){
 // CODE
}

```

is basically just a macro for:

```auto

ASSIGNMENT
while( EXPRESSION ) {
   // CODE

  ASSIGNMENT

}

```

Not to mention any of the expressions or assignments in either case can be omitted.

---

<div class="post-metadata">

**Author:** ![Bag\_of\_Mostly\_Water](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/bag_of_mostly_water/32/1029_2.png) [@Bag\_of\_Mostly\_Water](https://boards.straightdope.com/u/Bag_of_Mostly_Water)\
**Post date:** [December 30, 2011, 3:24pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/6 "2011-12-30T15:24:29Z")

</div>

Thanks for the comments.

**prt2void** , I’m leaving out details for clarity. This is pseudo-code.

**Jrgon** , I like your proposal. It also nicely shows the relationship between a for and while loop.

---

<div class="post-metadata">

**Author:** ![ptr2void](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/ptr2void/32/3406_2.png) [@ptr2void](https://boards.straightdope.com/u/ptr2void)\
**Post date:** [December 30, 2011, 3:24pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/7 "2011-12-30T15:24:42Z")

</div>

I should say, though, that the code can be shortened a little through the use of for, because you can put the initialization, termination, and decrement all in a single line:

```auto

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

int main() {
   char my_string[] = "This string has spaces at the end. ";
   char no_spaces[] = "This string has none";
   char *p = NULL;   
   for (p = &my_string[strlen(my_string) - 1]; *p == ' ' && p != my_string; --p) ;
   *(p+1) = '\0';
   printf("%s#
", my_string);
   for(p = &no_spaces[strlen(no_spaces) - 1]; *p == ' ' && p != no_spaces; --p) 
;
   *(p+1) = '\0';
   printf("%s#
", no_spaces);

   return 0;
}

```

---

<div class="post-metadata">

**Author:** ![robardin](https://avatars.discourse-cdn.com/v4/letter/r/43a26b/32.png) [@robardin](https://boards.straightdope.com/u/robardin)\
**Post date:** [December 30, 2011, 4:19pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/8 "2011-12-30T16:19:01Z")

</div>

Well, unless “remove\_last\_char()” does other magic like push the characters to another buffer, a one line for loop removes trailing whitespace very easily. Maybe that’s what your friend meant, a general preference for using for loops instead of while loops because of the ability to add initialization and increment/decrement commands all in one line of code. After all, if there’s anything “real C programmers” like to do it’s compressing code into as few lines as possible (usually in terms of compiled object code, but a close second is the aesthetic for compact lines of C code).

So if your C string is pointed to by “strbuf”, something like this (not tested):

```auto

for (char *lc = strlen(strbuf)-1; lc && lc > strbuf && *lc == ' '; *lc-- = '\0');

```

This will replace all trailing whitespace characters in strbuf with zero (null) chars.

Old Man Rant: Of course when _I_ learned C programming you had to declare “char \*lc” outside the loop first, this declaration-cum-initialization feature was only introduced with ANSI C in 1989, just as I was learning it. I spent over $40 (that’s 1989 dollars, mind you) buying a course book on C only to learn it was the older “K&R Edition” and eventually had to shell out another $40 or so to get the newer one.

---

<div class="post-metadata">

**Author:** ![robardin](https://avatars.discourse-cdn.com/v4/letter/r/43a26b/32.png) [@robardin](https://boards.straightdope.com/u/robardin)\
**Post date:** [December 30, 2011, 4:27pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/9 "2011-12-30T16:27:55Z")

</div>

> [@robardin](#):
>
> ```auto
> 
> for (char *lc = strlen(strbuf)-1; lc && lc > strbuf && *lc == ' '; *lc-- = '\0');
> 
> ```
> 
> This will replace all trailing whitespace characters in strbuf with zero (null) chars.

Ahh, I missed the addition to strbuf for the initialization. Goes to show even one-liners of a sort I’ve written a gazillion times are not immune to first-pass coding bugs 🙂

```auto

for (char *lc = **strbuf+** strlen(strbuf)-1; lc && lc > strbuf && *lc == ' '; *lc-- = '\0');

```

This will replace all trailing whitespace characters in strbuf with zero (null) chars.

---

<div class="post-metadata">

**Author:** ![steronz](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/steronz/32/11765_2.png) [@steronz](https://boards.straightdope.com/u/steronz)\
**Post date:** [December 30, 2011, 4:33pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/10 "2011-12-30T16:33:58Z")

</div>

Curiously, my first college programming professor forbade us from using FOR loops. We were basically learning C++, but he had written an obfuscation layer on top of it in order to make everything as generic as possible so that he could pitch it as a language-agnostic programming course. And, like **Jragon** said, the WHILE loop is the underlying structure of a FOR loop and was more universal at the time, so that’s all we had to work with.

It made it difficult later in life when I learned languages that seemed to prefer FOR loops.

---

<div class="post-metadata">

**Author:** ![robardin](https://avatars.discourse-cdn.com/v4/letter/r/43a26b/32.png) [@robardin](https://boards.straightdope.com/u/robardin)\
**Post date:** [December 30, 2011, 4:39pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/11 "2011-12-30T16:39:08Z")

</div>

More importantly though, the memory in the nulled-out characters is still pointed to by the original _strbuf_ pointer. Just because you’ve nulled out the characters doesn’t mean they’re not on the heap (if dynamically allocated).

I don’t know if you’re just learning C programming or not (so please excuse me if this is old news to you), but the elegance or efficiency of how you’re removing whitespace from strings is less important in the big picture than learning to code for a stable system. If only because you can always go back and optimize inefficient code, but it’s incredibly painful to hunt down memory leaks or pointer bugs in a large program.

While fun, rather than ask “can I code trailing whitespace removal in one line?” you may find it much more enlightening to describe what else is going on here… I have to say it smells a lot like a memory leak, or at worst something inefficient going on (like if “remove\_one\_char()” is calling reallloc() with every character removed).

---

<div class="post-metadata">

**Author:** ![beowulff](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/beowulff/32/542_2.png) [@beowulff](https://boards.straightdope.com/u/beowulff)\
**Post date:** [December 30, 2011, 4:40pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/12 "2011-12-30T16:40:59Z")

</div>

> [@robardin](#):
>
> Ahh, I missed the addition to strbuf for the initialization. Goes to show even one-liners of a sort I’ve written a gazillion times are not immune to first-pass coding bugs 🙂
> 
> ```auto
> 
> for (char *lc = **strbuf+** strlen(strbuf)-1; lc && lc > strbuf && *lc == ' '; *lc-- = '\0');
> 
> ```
> 
> This will replace all trailing whitespace characters in strbuf with zero (null) chars.

Im sorry, but I hate this style of coding.  
It’s too compact and difficult to interpret.  
I find it far better to have the code grouped in logical blocks, separated with braces. In general, the difference in object code is nil, and the source code is that much more maintainable.

---

<div class="post-metadata">

**Author:** ![robardin](https://avatars.discourse-cdn.com/v4/letter/r/43a26b/32.png) [@robardin](https://boards.straightdope.com/u/robardin)\
**Post date:** [December 30, 2011, 4:43pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/13 "2011-12-30T16:43:09Z")

</div>

I’d also like to state for the record that in a thread about C programming, **ptr2void** wins hands down for most appropriate username. 🙂

---

<div class="post-metadata">

**Author:** ![robardin](https://avatars.discourse-cdn.com/v4/letter/r/43a26b/32.png) [@robardin](https://boards.straightdope.com/u/robardin)\
**Post date:** [December 30, 2011, 4:53pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/14 "2011-12-30T16:53:21Z")

</div>

> [@beowulff](#):
>
> Im sorry, but I hate this style of coding.  
> It’s too compact and difficult to interpret.  
> I find it far better to have the code grouped in logical blocks, separated with braces. In general, the difference in object code is nil, and the source code is that much more maintainable.

I don’t disagree, just giving an example of what the OP’s friend may have had in mind. In particular the “pointer postcrement operator happens after dereferencing and use of a left-hand assignment” bit is a perfect example of an unnecessarily compact C programming aesthetic.

\*lc-- = ‘\0’;

Is two, even three lines of code in one. It’s great if you can read the shorthand quickly, which is great when all your programmers are veteran C coders… But after 10 years, when the majority of the folks maintaining it have C as their 4th language that they maybe only ever use to maintain the legacy code base, all those fun pointer shorthands are going to cause problems.

At the same time, appreciating that an inline postcrement is evaluated after an assignment while precrement happens before it is necessary for certain patterns of C++ STL programming (like removing entries of a set or map while iterating through it without corrupting the container traversal). But when I do that in Real Life, I put a couple of lines of comments there explaining what’s going on (in one case, even citing a page number in the book “Effective C++” by Scott Meyers :)).

---

<div class="post-metadata">

**Author:** ![engineer\_comp\_geek](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/engineer_comp_geek/32/504_2.png) [@engineer\_comp\_geek](https://boards.straightdope.com/u/engineer_comp_geek)\
**Post date:** [December 30, 2011, 4:55pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/15 "2011-12-30T16:55:17Z")

</div>

The problem with while loops is that if you screw up the conditional they never ever exit. At least with a for loop you are guaranteed to exit the loop. The for loop would be better in this case, but the idea that real programmers don’t use while loops is just silly. Breaks get confusing too sometimes, especially if you’ve got complicated nested conditionals. IMHO your “real” programmer’s code isn’t any better.

> [@robardin](#):
>
> ```auto
> 
> for (char *lc = strlen(strbuf)-1; lc && lc > strbuf && *lc == ' '; *lc-- = '\0');
> 
> ```

That’s starting to look way too much like line noise. Stuff like this is cute, but it’s a pain in the backside for anyone who ever has to do software maintenance.

The OP’s while loop is simple, clear, and to the point. IMHO, you should keep writing code like that.

---

<div class="post-metadata">

**Author:** ![Bag\_of\_Mostly\_Water](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/bag_of_mostly_water/32/1029_2.png) [@Bag\_of\_Mostly\_Water](https://boards.straightdope.com/u/Bag_of_Mostly_Water)\
**Post date:** [December 30, 2011, 8:31pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/16 "2011-12-30T20:31:58Z")

</div>

Thanks everyone for the comments. I managed to convince folks that a WHILE loop is perfectly acceptable. Being folks are getting into coding details, I’ll fill in a bit more.

The project is Objective-C for an iOS app. The code using the WHILE loop is

```auto

        NSString *temp = [textInputField text];
        while (([temp characterAtIndex:[temp length] - 1] == space) && ([temp length] > 0))
        {
            temp = [temp substringToIndex:[temp length] - 1];
        }

```

The variable textInputField is declared as UITextField and space is defined as 32 (ACSII space). Unless you’re familiar with Objective-C syntax, this probably does not make much sense. That’s why I used the pseudo code in the OP.

---

<div class="post-metadata">

**Author:** ![Reno\_Nevada](https://avatars.discourse-cdn.com/v4/letter/r/6f9a4e/32.png) [@Reno\_Nevada](https://boards.straightdope.com/u/Reno_Nevada)\
**Post date:** [December 30, 2011, 9:43pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/17 "2011-12-30T21:43:42Z")

</div>

> [@Bag\_of\_Mostly\_Water](#):
>
> The project is Objective-C for an iOS app. The code using the WHILE loop is

I DON’T know Objective-C (any longer; I used to) but this does smell a little like you are copying the string each pass through the loop, which I would regard as…suboptimal.

> [@](#):
>
> The OP’s while loop is simple, clear, and to the point. IMHO, you should keep writing code like that.

I agree whole-heartedly with this point.

---

<div class="post-metadata">

**Author:** ![TriPolar](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tripolar/32/3008_2.png) [@TriPolar](https://boards.straightdope.com/u/TriPolar)\
**Post date:** [December 30, 2011, 9:51pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/18 "2011-12-30T21:51:25Z")

</div>

Whatever you do, it should be put in a function. It is simple and can easily be re-written to optimize. As long as the input and output of the function is well defined, no one working on code outside the function should be concerned with how it is coded.

That said, a WHILE is going to be inefficient. Strings are arrays of characters ideally suited for FOR loops.

---

<div class="post-metadata">

**Author:** ![Digital\_is\_the\_new\_Analog](https://avatars.discourse-cdn.com/v4/letter/d/a88e4f/32.png) [@Digital\_is\_the\_new\_Analog](https://boards.straightdope.com/u/Digital_is_the_new_Analog)\
**Post date:** [December 30, 2011, 10:06pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/19 "2011-12-30T22:06:07Z")

</div>

> [@TriPolar](#):
>
> That said, a WHILE is going to be inefficient. Strings are arrays of characters ideally suited for FOR loops.

Depending on how you write things..

Modern compilers do pretty cool stuff to loops. Unrolling them to get better use of pipelining of instructions. Changing around conditions to use hardware native instructions. Stuff like that.

Unless you know the specifics of your architecture and your compiler, I wouldn’t suggest one style as more efficient than the other for the general case.  
-D/a

---

<div class="post-metadata">

**Author:** ![TriPolar](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tripolar/32/3008_2.png) [@TriPolar](https://boards.straightdope.com/u/TriPolar)\
**Post date:** [December 30, 2011, 10:14pm UTC](https://boards.straightdope.com/t/c-programming-question/607832/20 "2011-12-30T22:14:09Z")

</div>

> [@Digital\_is\_the\_new\_Analog](#):
>
> Depending on how you write things..
> 
> Modern compilers do pretty cool stuff to loops. Unrolling them to get better use of pipelining of instructions. Changing around conditions to use hardware native instructions. Stuff like that.
> 
> Unless you know the specifics of your architecture and your compiler, I wouldn’t suggest one style as more efficient than the other for the general case.  
> -D/a

It may be possible a compiler can optimize a WHILE to match the performance of an optimized FOR, but unlikely to exceed it. But the WHILE would have to be written to allow that. Incrementing FOR loops, even without optimization, compile into very dense rapidly executing code.
