-2
int NameAbbreviation() {
  if (name_last[1] <= 'a' && name_last[1] >= 'b') {
    return name_last[1] += 'A' - 'a';
  }
  printf("%c%c%c", name_first[0], name_last[0], name_last[1]);
}

Hello community my previous questions didn't received good feedback, hope this one doesn't bother you same as my last question.

In this small sample code I try to capitalise the second letter of a char array to safe it later in an own variable called name_abbreviation. Since the code doesn't transform the letter into capital I wonder how I can access letters specific in arrays to change the content and save it.

I don't get any errors but the code doesn't execute the if statement. Name_last[i] is the input value.

LIT
  • 73
  • 10
  • 4
    I think your condition is always false. – Youssef13 Jan 14 '20 at 12:49
  • 1
    Unless you're on a **very** peculiar computer, one single letter (or symbol, really) will never be at the same time less than `'a'` and more than `'b'`. It certainly does not happen on ASCII-based computers nor on EBCDIC-based computers. – pmg Jan 14 '20 at 12:50
  • 2
    Your function also doesn't return a value in all code paths. – Youssef13 Jan 14 '20 at 12:50
  • 1
    Don't do the upper-casing yourself, use [`toupper`](https://en.cppreference.com/w/c/string/byte/toupper) (which will do the right thing even on systems with odd encodings). – Some programmer dude Jan 14 '20 at 12:54
  • Changing your conditional line as `offset = 'A' - 'a'; if (name_last[1] < 'a' || name_last[1] > 'z') { name_last[1] -= offset; }` would work. As ascii codes are numbered in sequence from A to Z and a to z, a letter cannot be *less than or eq to 'a' and greater than or equal to 'b'* at the same time. You should use or (`||`) in stead of and (`&&`). Moreover, you need to erase the `return`; keeping `return` will exit function immediately, without reaching the `printf` line. Another correction: as 'A - Z' comes before 'a - z', you need to decrement (`-`) not increment (`+`) the value. – ssd Jan 14 '20 at 13:15
  • @LIT: For one, your code example is not complete. Anything that we cannot take, copy, paste, compile, and run to see the exact same result as you do (without having to type in the "right" input) is not really a good "why does this not work" question. Your question is also not very precise, and will even in the best case be of limited use to anybody else. Not my downvote, just to explain why people might consider voting it down. – DevSolar Jan 14 '20 at 13:53
  • @ssd: Every time someone tells somebody else that assuming ASCII-7 is OK, a kitten dies... – DevSolar Jan 14 '20 at 13:56
  • 1
    I would be very careful about about assuming the existence of `name_last[1]`. – Neil Jan 14 '20 at 19:23
  • Don't really know what you want to say with that @Neil – LIT Jan 14 '20 at 20:34
  • I mean that if you had a `last_name` of "A", you'll be outputting null to the console. With `last_name` as an empty string, you are (probably) going to invoke undefined behaviour. – Neil Jan 14 '20 at 20:52
  • Yes the correction to the code of DevSolar was working – LIT Jan 14 '20 at 21:32

2 Answers2

0

Depending on the encoding used, 'a' through 'z' need not be in sequence; but since they are on virtually all modern machines, your condition will likely never be true. In any case you should not do arithmetics with character literals. Try the more idiomatic...

#include <ctype.h>

...and...

if ( isalpha( (unsigned char)name_last[1] ) )

...and...

return toupper( (unsigned char)name_last[1] )

Also note that a function declared to return int needs to return int in all cases. You do not have a return /* something */ after your printf...

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • Hello DevSolar the capitalisation works, but there is very strange behaviour now. printf("%c\n", name_last[1]); gives two output first is capital I and second is lower i. Hahaha how is this possible – LIT Jan 14 '20 at 13:20
  • @LIT: It is not. There has to be something else going on. (Your example code is not complete, so I cannot reproduce what you're seeing.) – DevSolar Jan 14 '20 at 13:42
  • Thanks to @P__J__ I can share the code with you. https://godbolt.org/z/F5Wfrc. – LIT Jan 14 '20 at 13:56
  • @LIT: ...and if you had tried to reduce that code even further, until you end up with one function working on one hardcoded string, you'd have realized that you got a bit confused with `name_full`, `name_first`, `name_last`, `name_abbreviation`, and your outputs. ;-) Third line of output (`II`) is the `putchar( toupper(...name_last[1]...))`, followed by the `printf("%c\n", name_abbreviation[1])`. The next line (`TIi`) is the `printf("%c%c%c", name_first[0], name_last[0], name_last[1])`. I guess you forgot about the `putchar()`. – DevSolar Jan 14 '20 at 14:06
  • So you don't see how the 3rd printf statement produces two outputs instead of one? – LIT Jan 14 '20 at 14:08
  • @LIT: The program is doing *exactly* what you told it to do. (Programs always do. You just *think* you told it something else.) The `printf("%c\n", name_abbreviation[1])` prints one character and a newline *to a line in which there is already one character due to the `putchar()` from source line 32*. – DevSolar Jan 14 '20 at 14:10
  • I will change the whole thing to a more compact and logical code. But the fact that I'm currently learning the language makes it difficult to always start in the easiest way ;) – LIT Jan 14 '20 at 14:11
  • Ah I see didn't knew that putchar creates an output. Thanks for your support! – LIT Jan 14 '20 at 14:13
  • @LIT: If I may be so bold, whatever you are using as course material, pick something else. You should have been steered well clear of this `- 'a'` stuff, and you should know a lot more about functions and pointers already. Also, while being a "simple" language (as in, not that much in there to learn), C isn't exactly a simple language *to* learn, because simple things already require so much to *do*. For something as simple as entering a string, doing something with it, and then printing it again you *already* have to touch on arrays, pointers, and variadic arguments... – DevSolar Jan 14 '20 at 14:14
  • (ctd.) While many people will disagree with me, I consider C++ an *easier* language to learn, **if** you have access to good material / a good tutor, because you can do things much more intuitively, and don't need to build things from toothpicks and glue. You can go *down* to that level, but you don't have to *start* there. And unless you've got specific reasons for preferring C (or C++), Java or Python are more mainstream, and provide a somewhat more approachable introduction to programming. (Not that I want to discourage you from anything. I'm teaching beginner C++ myself.) – DevSolar Jan 14 '20 at 14:16
  • I always was curious why anyone hates C. Now I know since C++ is the extension and it works for most micro controller it's after 3 days of learning clear that C++ is the better language to learn. I mean I also don't learn machine code for coding no need to work with this archaic stuff :) Thanks man I learned a lot from you! – LIT Jan 14 '20 at 14:25
  • @LIT: If you go for C++, try to find course material / books that do **not** "start with C". That's the wrong way to approach C++. Even if you don't understand much of what she talks *about*, do watch Kate Gregory's ["Stop Teaching C"](https://www.youtube.com/watch?v=YnWhqhNdYyk) talk from CppCon 2015. It will give you an idea of what to look for in teaching materials or courses. (And, please, *do* find teaching materials. While "better" than C, C++ is *very much not* a "trial and error" language. You need guidance, or you *will* get lost.) – DevSolar Jan 14 '20 at 14:44
  • @LIT: In one sentence, if it starts with `char *`, `printf()`, `[]` arrays, pointer manipulation, or taking "naked" pointers from `new` (without a `unique_ptr` or `shared_ptr` in sight)... I'd keep looking for a better C++ course. ;-) – DevSolar Jan 14 '20 at 14:54
  • I don't learn with courses. I take books sample codes stack overflow and manuals from universities like ETH MIT or equal. But just the fact that there is classes makes C useless – LIT Jan 14 '20 at 14:56
  • Modern `C++` is very different than old `C++`, and a lot of books have been written about old `C++`. If you don't see `unique_ptr` and `shared_ptr`, it's probably out-of-date. `C` is a great language but it makes it easy (for beginners, especially) to write un-maintainable code. – Neil Jan 15 '20 at 20:02
  • @Neil: My (and Kate Gregory's) advice actually goes a lot further than that. As long as you understand C++ as an "add-on" to C, you're doing yourself and the language a disservice. You should tackle C++ *from the top*, and reserve the "C compatibility layer" (e.g. arrays, pointers) for last. – DevSolar Jan 16 '20 at 10:04
  • I agree; C++ and C are very different languages, despite the similarity in some syntax. – Neil Jan 16 '20 at 16:43
0

https://godbolt.org/z/v2uTs2

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

char *toUpperX(char *str, size_t pos)
{
    if(str && pos < strlen(str))
    {
        str[pos] = toupper(str[pos]);
    }
    return str;
}

int main(int argc, char **argv)
{
    char str[] = "Asdgh 457678 /\\we";

    printf("Before: %s", str);
    printf("\tAfter: %s\n", toUpperX(str, 1));
}
0___________
  • 60,014
  • 4
  • 34
  • 74
  • Thank you very much the code works well, but it's very complex for a simple task like this. – LIT Jan 14 '20 at 13:15
  • Can you tell me what is complex? The function is 8 lines long – 0___________ Jan 14 '20 at 13:17
  • For me as a newbie it's very complex to understand it. Since I have no clue what is the asterisk before the function and also why you have strlen inside also no clue if pos is a variable. Gives me like 233 questions this 8 lines of code :). But it works I just don't see how. Thanks for the help – LIT Jan 14 '20 at 13:23
  • 1
    The argument to `toupper()` needs to be `unsigned char`. See https://stackoverflow.com/questions/21805674/do-i-need-to-cast-to-unsigned-char-before-calling-toupper-tolower-et-al – Andrew Henle Jan 14 '20 at 19:20