The following code is broken when trying to run due to an issue replacing the character on line 33. Am I replacing the character in the string incorrectly?
The code is designed to encrypt lowercase characters in the *cat string. Each character in code2 is 'mapped' to a character in the same position in code1. The lowercase chars in *cat are replaced with their substituted char from code2.
//Ben Adamson
//v1.0
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
void code(char *s);
int main()
{
char *cat = "The cat sat";
code(cat);
_getch();
return 0;
}
void code(char *s)
{
char code1[] = "abcdefghijklmnopqrstuvwxyz";
char code2[] = "bpduhijkaltxwmrzfoysvngeqc";
char *letter;
unsigned int i, letterpos;
for(i=0; i<strlen(s); i++)
{
if(isalpha(s[i]) && islower(s[i]))
{
letter = strchr(code1, s[i]);
letterpos = (int)(letter - code1);
s[i] = code2[letterpos];
}
}
printf("New string is %s", s);
}
char *cat = "The cat sat";
Her cat is read only.
s[i] = code2[letterpos];
You need to allocate memory if you need to write to it.
char *cat = malloc(100);
Better way to do it is:
char *cat = strdup("The cat sat");
Related
I need to print the initials of a name, like tyler jae woodbury would print TJW, but I can't seem to print the uppercase initials.
This is my code:
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
string get_initials(string name, char initials[]);
int main(void)
{
// User input
string name = get_string("Name: ");
// Gets the users initials
char initials[10];
get_initials(name, initials);
printf("%s\n", initials);
}
string get_initials(string name, char initials[])
{
int counter = 0;
for (int i = 0, n = strlen(name); i < n; i++)
{
if (name[i] == ' ')
{
initials[counter] = name[i+1];
counter++;
}
else if (i == 0)
{
initials[counter] = name[i];
counter++;
}
}
return initials;
}
I know that usually toupper() is used for chars, and the print statement declares a string, but I don't know what to do.
The function is incorrect.
For starters in general a string can contain adjacent spaces between words or have trailing adjacent spaces.
Secondly the function does not build a string because it does not append the terminating zero character '\0' to the destination array.
Also the call of strlen is inefficient and redundant.
To convert a symbol to upper case use standard function toupper declared in the header <ctype.h>
Also the function declaration is confusing
string get_initials(string name, char initials[]);
Either use
string get_initials(string name, string initials);
or it will be better to write
char * get_initials( const char *name, char *initials);
The function can be defined the following way as shown in the demonstration program below.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char * get_initials( const char *name, char *initials )
{
const char *blank = " \t";
char *p = initials;
while ( name += strspn( name, blank ), *name )
{
*p++ = toupper( ( unsigned char )*name );
name += strcspn( name, blank );
}
*p = '\0';
return initials;
}
int main( void )
{
char name[] = " tyler jae woodbury ";
char initials[10];
puts( get_initials( name, initials ) );
}
The program output is
TJW
I am trying to use a for loop with ASCII table to make every character in the string uppercase one by one by subtracting the letter number with 32. but I cant use the int i in the char str and str2. how can I do this?
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define STRLEN 200
void string_lower() {
}
void string_upper(char str) {
char str2;
int length = strlen(str);
for (int i = 0; i < length; i++) {
str2[i] = str[i - 32];
}
}
int main() {
char word[STRLEN] = { 0 };
char word1 = 97;
printf("Write a word");
fgets(word, STRLEN, stdin);
string_upper(word);
return 0;
}
You can use toupper() to uppercase one character at a time. This will work for single byte character sets such as ASCII, but not for the UTF-8 encoding in general use today for non English scripts.
Here is a modified version:
#include <ctype.h>
#include <stdio.h>
#define STRLEN 200
char *string_upper(char *str) {
for (size_t i = 0; str[i] != '\0'; i++) {
str[i] = toupper((unsigned char)str[i]);
}
return str;
}
int main() {
char word[STRLEN];
printf("Enter a word: ");
if (fgets(word, STRLEN, stdin)) {
printf("%s", string_upper(word);
}
return 0;
}
The argument must be cast as (unsigned char)str[i] because str[i] has type char and tolower() like all functions and macros from <ctype.h> is only defined for values of the type unsigned char and the special negative value EOF. As char may be signed on some platforms, passing it directly to tolower() would have undefined behavior for negative values such as 'é' and 'ÿ'.
If you just want to make a function to convert your String to upper, maybe you can refer to the below example.
#include <stdio.h>
#include <ctype.h>
#define STRLEN 200
void string2upper(char *str){
int cursor=0;
while(*(str+cursor)!='\0'){
*(str+cursor) = toupper(*(str+cursor));
cursor++;
}
}
void main() {
char String1[STRLEN];
printf("Write a word:\n");
fgets(String1, STRLEN, stdin);
printf("Before : %s\n", String1);
string2upper(String1);
printf("After : %s\n", String1);
}
For the toupper() function, I think you can refer to this Link.
That has a detailed explanation and simple example to understand.
I think to know the function detail is better than only using~
I want to capitalize the first character of a pointer string.
For example, input: john
Output: John
I can do it with arrays (s[0] = toUpper(s[0]), but is there a way to do it with pointers?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 30
int transform(char *s)
{
while (*s != '\0')
{
*s = toupper(*s);
s++;
}
return *s;
}
int main()
{
printf("String: ");
char *s[MAX];
getline(&s,MAX);
transform(s);
printf("Transformed char: %s", &s);
}
int getline(char *s, int lim)
{
int c;
char *t=s;
while (--lim>0 && (c=getchar())!=EOF && c!='\n') *s++=c;
*s='\0';
while (c!=EOF && c!='\n')
c=getchar();
return s-t;
}
This code turns the whole string to upper case.
Your transform function is looping through the entire string and running toupper on each one. Just run it on the first character:
void transform(char *s)
{
*s = toupper(*s);
}
Also, you declare s in main as an array of pointers to char. You just want an array of char:
int main()
{
printf("String: ");
char s[MAX];
getline(s,MAX); // don't take the address of s here
transform(s);
printf("Transformed char: %s", s); // or here
}
You want to move main to the end of the file as well, so that getline is defined before it is called.
Easy solution:
void transform(char* p) {
//Only first character
*p = toupper(*p);
}
//Call like that:
char str[] = "test";
transform(str); //str becomes: "Test"
I have the following string abcd1234 and I want to find a way to break this string into two different strings, abcd and 1234. I have tried the following code:
char buf[100],*str1,*str2;
int x;
fgets(buf,sizeof(buf),stdin);
str1=strtok(buf,"0123456789 \t\n");
str2=strtok(NULL," \n\t\0");
puts(str1);
puts(str2);
x=atoi(str2);
printf("x=%d", x);
but output is abcd 234. And if I try it with one letter and one number, e.g a2 I take only e on output and x is 0.
As per the man page of strtok()
Each call to strtok() returns a pointer to a null-terminated string containing the next token. This string does not include the delimiting byte. [...]
So, while using "0123456789 \t\n" as the delimiter for the first time, 1 will be treated as the actual delimiter and will not be considered in the subsequent parsing.
You may want to use strcspn() and/or strpbrk() to find out the index for the required sub-strings and parse accordingly.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
size_t extract(const char **sp, char *out, int (*test)(int ch));
int main(void){
char buf[100], str1[100], str2[100];
int x;
const char *p = buf;
//size_t len;
fgets(buf, sizeof(buf), stdin);
while(*p){
if(isalpha((unsigned char)*p)){
extract(&p, str1, isalpha);
puts(str1);
} else if(isdigit((unsigned char)*p)){
extract(&p, str2, isdigit);
x = atoi(str2);
printf("%s, x=%d\n", str2, x);
} else {
++p;//skip one char
}
}
return 0;
}
size_t extract(const char **sp, char *out, int (*test)(int ch)){
const char *p = *sp;
while(*p && test((unsigned char)*p)){
*out++ = *p++;
}
*out = '\0';
size_t len = p - *sp;
*sp = p;
return len;
}
Try below code.Hope this will help you.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char string[]="abcd1234";
char digitStr[10];
char charStr[10];
int i,j = 0,k = 0;
for(i=0;string[i];i++)
{
if(isdigit(string[i]))
{
charStr[j++]=string[i];
}
else
{
digitStr[k++]=string[i];
}
}
charStr[j] = '\0';
digitStr[k] = '\0';
printf("%s %s\n",digitStr,charStr);
}
I realize I'm very late on this one, but this is for if anyone has a similar case
Assuming all input strings are like your example, this method will work.
char buf[100];
fgets(buf, sizeof(buf), stdin);
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
int x = atoi(strpbrk(buf, "0123456789"));
char letters[number - buf + 1];
memcpy(letters, sizeof(letters) - 1, buf);
letters[sizeof(letters) - 1] = '\0';
//letters is the word
//x is the number as an int, not a string
• Note the if statement after the fgets. This checks that the newline character was read by fgets, and turns it into a NUL character. (essentially truncating the string).
• As for strpbrk(), that's just a function that returns a pointer to the first occurence of any character in the second string inside the first string. I use it here to find the start of the digit sequence.
• I would also drop the atoi() for strtol() for safety.
• The letters[] array size is the return of strpbrk() (the address of the first number), minus the start of the array (giving the length of the letter string in bytes), plus one for the NUL character I add later.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Remove characters from a string in C
Do you have an example of C code to remove carriage returns in a string?
The simplest solution is to probably just process the string character by character, with pointers for source and destination:
#include <stdio.h>
#include <string.h>
int main (void) {
char str[] = "This is a two-line\r\nstring with DOS line endings.\r\n";
printf("%d [%s]\n",strlen(str), str);
// ========================
// Relevant code in this section.
char *src, *dst;
for (src = dst = str; *src != '\0'; src++) {
*dst = *src;
if (*dst != '\r') dst++;
}
*dst = '\0';
// ========================
printf("%d [%s]\n",strlen(str), str);
}
This sets up two pointers initially the same. It then copies a character and always advances the source pointer. However, it only advances the destination pointer if the character wasn't a carriage return. That way, all carriage returns are overwritten by either the next character or the null terminator. The output is:
51 [This is a two-line
string with DOS line endings.
]
49 [This is a two-line
string with DOS line endings.
]
This would be adequate for most strings. If your strings are truly massive in size (or this is something you need to do many times each second), you could look at a strchr-based solution since the library function will most likely be optimised.
A carriage return or any other char is easy to replace in a string and even easier to replace. Your question does not really shows what you're looking for so I've included sample code for both removing and replacing a char in a string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void remove_char_from_string(char c, char *str)
{
int i=0;
int len = strlen(str)+1;
for(i=0; i<len; i++)
{
if(str[i] == c)
{
// Move all the char following the char "c" by one to the left.
strncpy(&str[i],&str[i+1],len-i);
}
}
}
void replace_char_from_string(char from, char to, char *str)
{
int i = 0;
int len = strlen(str)+1;
for(i=0; i<len; i++)
{
if(str[i] == from)
{
str[i] = to;
}
}
}
int main(void) {
char *original = "a\nmultiline\nstring";
int original_len = strlen(original)+1;
char *string = (char *)malloc(original_len);
memset(string,0,original_len);
strncpy(string,original,original_len);
replace_char_from_string('\n',' ',string);
printf("String: %s\n",string); // print: String: a multiline string
remove_char_from_string(' ',string);
printf("String: %s\n",string); // print: String: amultilinestring
return 0;
}