I want to replace every backslash in a string with two backslashes.
I use this code:
#include <stdio.h>
int main()
{
int iD, iM, iY = 0;
char str[255] = "C:\\Users\\Documents";
printf("%s \n", str);
int i = 0;
for(i = 0 ; i < (unsigned)strlen( str ) ; i++)
{
if ( str[i] == '\\')
{
str[i] == "\\\\";
}
}
printf("%s", str);
return 0;
}
Output : C:\Users\Documents
Expected Result : C:\\Users\\Documents
You can't simply replace a single character with two characters! The simplest way to achieve your result is to have a second string, then copy from old to new, one character at a time, adding an extra backslash when that is the character just copied.
Here's a working sample that does this:
#include <stdio.h>
#include <string.h>
int main()
{
char str[255] = "C:\\Users\\Documents";
char newstr[ 2 * sizeof(str) ]; // As suggested by "chux" - ensure buffer is big enough!
printf("%s \n", str);
int i, j;
for (i = j = 0; i < (int)strlen(str); i++, j++) {
newstr[j] = str[i];
if (str[i] == '\\') newstr[++j] = '\\'; // Insert extra backslash
}
newstr[j] = '\0'; // We need to add nul-terminator!
printf("%s", newstr);
return 0;
}
Of course, you could always replace the original string with the new one, once you've done the transformation, with a simple strcpy(str, newstr); line.
Related
The following code I found on tutorialgateway is used to remove all duplicate characters from a string.
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
int i, j, k;
printf("\n Please Enter any String : ");
gets(str);
for(i = 0; i < strlen(str); i++)
{
for(j = i + 1; str[j] != '\0'; j++)
{
if(str[j] == str[i])
{
for(k = j; str[k] != '\0'; k++)
{
str[k] = str[k + 1];
}
}
}
}
printf("\n The Final String after Removing All Duplicates = %s \n", str);
return 0;
}
I thought if I changed the == for != on the if statement it would instead remove all unique or non duplicate characters, but instead it does something else. What am I not understanding about how this code works?
Your solution will take approximately O(n^3).
Also, having three nested loops adds needless complexity.
If we change the algorithm to use a frequency table, we can reduce complexity. And, we can reduce the running time to 2*O(n) or O(n).
Side note: Never use gets. See: Why is the gets function so dangerous that it should not be used?
Here is the refactored code:
#include <stdio.h>
#include <string.h>
int
main()
{
char str[100];
char freq[256] = { 0 };
char *src;
char *dst;
unsigned char chr;
printf("\n Please Enter any String : ");
fgets(str,sizeof(str),stdin);
str[strcspn(str,"\n")] = 0;
printf("\n The Original String = %s \n", str);
// get frequency count
src = str;
for (chr = *src++; chr != 0; chr = *src++) {
switch (freq[chr]) {
case 0: // new [unique] char
freq[chr] = 1;
break;
default: // duplicate
freq[chr] = 2;
break;
}
}
dst = str;
src = str;
// copy over chars that are unique
for (chr = *src++; chr != 0; chr = *src++) {
if (freq[chr] == 1)
*dst++ = chr;
}
*dst = 0;
printf("\n The Final String after Removing All Duplicates = %s \n", str);
return 0;
}
Here is the program output:
Please Enter any String :
The Original String = abbbbbbbbbccdefghe
The Final String after Removing All Duplicates = adfgh
I want to print the length of each word in a string.
I have tried but not getting right answer. After running the code it will print the length of each word after the word instead of printing before the each word.
char str[20] = "I Love India";
int i, n, count = 0;
n = strlen(str);
for (i = 0; i <= n; i++) {
if (str[i] == ' ' || str[i] == '\0') {
printf("%d", count);
count = 0;
} else {
printf("%c", str[i]);
count++;
}
}
I except the output is 1I 4Love 5India, but the actual output is I1 Love4 India5.
You can use strtok as Some programmer dude sugested. You may want to make a copy of the original string as strtok modifies the passed string. Also strtok is not thread-safe and must be replaced with strtok_r when working with multi-threaded programs.
#include <stdio.h>
#include <stdlib.h>
/* for strtok */
#include <string.h>
int main() {
char str[20] = "I Love India";
int n;
char* tok = strtok(str, " ");
while (tok != NULL) {
n = strlen(tok);
printf("%d%s ", n, tok);
tok = strtok(NULL, " ");
}
return EXIT_SUCCESS;
}
You want to compute and print the length of each word before you print the word.
Here is a simple solution using strcspn(), a standard function that should be used more often:
#include <stdio.h>
#include <string.h>
int main() {
char str[20] = "I Love India";
char *p;
int n;
for (p = str; *p;) {
if (*p == ' ') {
putchar(*p++);
} else {
n = strcspn(p, " "); // compute the length of the word
printf("%d%.*s", n, n, p);
p += n;
}
}
printf("\n");
return 0;
}
Your approach is wrong as you print the word before the length. So you need to calculate the length first then print it and then print the word.
It could be something like:
int main(void)
{
char str[20]="I Love India";
size_t i = 0;
while(str[i])
{
if (str[i] == ' ') // consider using the isspace function instead
{
// Print the space
printf(" ");
++i;
}
else
{
size_t j = i;
size_t count = 0;
// Calculate word len
while(str[j] && str[j] != ' ')
{
++count;
++j;
}
// Print word len
printf("%zu", count);
// Print word
while(i<j)
{
printf("%c", str[i]);
++i;
}
}
}
}
The basic idea is to have two index variables for the string, i and j. The index i is at the words first character and index j is used for finding the end of the word. Once the end of word has been found, the length and the word can be printed.
This is what you want:
#include <stdio.h>
#include <string.h>
int main()
{
char str[20]="I Love India";
char buf[20];
int i,n,count=0;
n=strlen(str);
for (i=0; i <= n; i++) {
if(str[i]==' ' || str[i]=='\0'){
buf[count] = '\0';
printf("%d", count); /* Print the size of the last word */
printf("%s", buf); /* Print the buffer */
memset(buf, 0, sizeof(buf)); /* Clear the buffer */
count = 0;
} else {
buf[count] = str[i];
count++;
}
}
return 0;
}
You will want to keep a buffer of the word that is currently being counted. (buf)
Increment count each time its not a space or 0/. Then, when it is a space or a 0/, print count first, then buf. Then, we will clear buf and set count to 0, so that the variable i is still incrementing through the entire string str, but we are inserting the words into buf starting from 0.
I am trying to get rid of all \ characters in a string in C. For example, if a string is co\din\g it should convert the string to coding.
So far I have the code
for(i = 0; i < strlen(string); ++i){
if(string[i] == '\'){
}
}
That looks to see if there is a backslash. I don't know how I would do to remove the backslash, however. My only idea is to set the next character equal to the current character, however, I don't know how changing the length of the string would work with memory.
like this:
#include <stdio.h>
int main(){
char st[] = "co\\din\\g";
int k = 0;
for (int i = 0; st[i] != '\0'; ++i)
if (st[i] != '\\')
st[k++] = st[i];
st[k] = '\0';
fputs(st, stdout);
return 0;
}
This works. Since you're only deleting characters, you can write back into the same string. At the end, the termination '\0' will move to a lower index, and the rest of the array will simply be ignored by printf. Also, \ is the escape character, so to pass the \ itself you must write \\.
#include <stdio.h>
void nukechar(char s[], char c)
{
size_t j = 0;
for (size_t i = 0; s[i] != '\0'; ++i) {
if (s[i] != c) {
s[j] = s[i];
++j;
}
}
s[j] = '\0';
}
int main(void)
{
char s[200];
while (fgets(s, 200, stdin) != NULL) {
nukechar(s,'\\');
printf("%s", s);
}
return 0;
}
The simplest solution would be to use a second string for the result:
#include <stdio.h>
#include <string.h>
int main(void)
{
char result[100] = {'\0'}, string[] = "co\\din\\g";
for(int i = 0, j = 0; i < strlen(string); i++)
{
if(string[i] != '\\')
result[j++] = string[i];
}
printf("%s %s\n", result, string);
return 0;
}
Result
$ gcc main.c -o main.exe; ./main.exe;
coding co\din\g
Note
It is necessary to use double backslashes, \\, so the character following the backslash is not interpreted as an escape sequence.
This is my code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void splitString(char s[]) {
char firstHalf[100] = { 0 };
char secndHalf[100] = { 0 };
for (int i = 0; i < strlen(s) / 2; i++){
firstHalf[i] = s[i];
}
for (int i = strlen(s) /2; i < strlen(s); i++){
secndHalf[i - strlen(s) / 2] = s[i];
}
printf("The string split in two is '%s, - %s' \n", firstHalf, secndHalf);
}
void upperCase(char s[]){
//String in upper case
for (size_t i = 0; i < strlen(s); i++)
s[i] = toupper(s[i]);
printf("The string in uppercase is '%s'", s);
}
void lowerCase(char s[]){
//String in lower case
for (size_t i = 0; i < strlen(s); i++)
s[i] = tolower(s[i]);
printf("The string in lowercase is '%s'", s);
}
int main() {
char s[200];
char splitS[200];
printf("Type a string: ", sizeof( s));
if (fgets(s, sizeof(s), stdin) != 0){
printf("The string is '%s'", s);
}
strcpy(splitS, s);
upperCase(s);
lowerCase(s);
splitString(splitS);
return 0;
}
The correct way it's supposed to print is like this:
The string is 'Hello world'
The string in uppercase is 'HELLO WORLD'
The string in lowercase is 'hello world'
The string split in two is 'Hello, - world'
But instead it prints like this:
The string is 'Hello world
'The string in uppercase is 'HELLO WORLD
'The string in lowercase is 'hello world
'The string split in two is 'Hello , - world
'
You need to read the documentation for fgets() (my emphasis):
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.
Since you are typing in these lines with line break characters at the end, you need to remove them in your code.
You have to put null terminator
void splitString(char s[]) {
char firstHalf[100] = { 0 };
char secndHalf[100] = { 0 };
// u need to add null terminator '\0' at the end of string
// so u can add it in for loop or set i outside of loop
for (size_t i = 0; i < strlen(s) / 2; i++){
firstHalf[i] = s[i];
**firstHalf[i+1] = '\0';**
}
for (size_t i = strlen(s) /2; i < strlen(s); i++){
secndHalf[i - strlen(s) / 2] = s[i];
**secndHalf[i+1] = '\0';**
}
printf("The string split in two is '%s, - %s' \n", firstHalf, secndHalf);
}
The fgets function will read a newline and append it to the input string of there's room for it.
You need to check if the last character in the string is \n and if so set it to zero to trim it.
This is happening because fgets retains a newline at the end of the input string, and also because you do not printf a newline yourself.
So the result, is that newline is being printed in the wrong place, splitting your message, and the ' appears on the next line.
An easy way to remove the newline from the entry is with
s [ strcspn(s, "\r\n") ] = 0;
but don't forget to add the \n to the end of the printf formatting strings.
I thing use scanf with format specifier %[^\n]s so you can skip the new line instated of fgets and add \n in every printf.
Complete working code :
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void splitString(char s[]) {
char firstHalf[100] = { 0 };
char secndHalf[100] = { 0 };
int i;
for ( i = 0; i < strlen(s) / 2; i++){
firstHalf[i] = s[i];
}
for ( i = strlen(s) /2; i < strlen(s); i++){
secndHalf[i - strlen(s) / 2] = s[i];
}
printf("\n The string split in two is '%s, - %s' \n", firstHalf, secndHalf);
}
void upperCase(char s[]){
//String in upper case
int i;
for (i = 0; i < strlen(s); i++)
s[i] = toupper(s[i]);
printf("\n The string in uppercase is '%s'", s);
}
void lowerCase(char s[]){
//String in lower case
int i;
for ( i = 0; i < strlen(s); i++)
s[i] = tolower(s[i]);
printf("\n The string in lowercase is '%s'", s);
}
int main() {
char s[200];
char splitS[200];
printf("Type a string: %ld", sizeof( s));
if (scanf("%200[^\n]s", s)!= 0){ //fgets(s, sizeof(s), stdin)
printf("\n The string is '%s'", s);
}
strcpy(splitS, s);
upperCase(s);
lowerCase(s);
splitString(splitS);
return 0;
}
OR
if you want use fgets only then find new line char in string and make it NULL and add new line char '\n' in every printf .
Code need to change is:
if ( fgets(s, sizeof(s), stdin) != 0){
int i;
for(i = 0 ; i < sizeof( s) ; i++ ){
if(s[i] == '\n'){
s[i] = '\0';
break;
}
}
printf("\n The string is '%s'", s);
}
In the str char array below I would first like to locate the first math symbol I see, then I would like to count backwards and remove whatever is between the previous three "_" and remove the three "_". Can I please get some ideas on how to do this?
So this:
xa_55_y_*_z_/_+_x_+
Should turn into:
xa*_z_/_+_x_+
My problem is I don't know how to remove:
_55_y_
Here is the code so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
char str [] = "xa_55_y_*_z_/_+_x_+";
int length = 0;
int decrementor = 0;
int underscore_counter = 0;
int i = 0;
length = strlen (str);
for(i = 0; i < length; i++)
{
decrementor = 0;
underscore_counter = 0;
if(str[i] == '*' || str[i] == '/' || str[i] == '+' || str[i] == '-')
{
decrementor = i;
while(underscore_counter != 3)
{
if(str[decrementor] == '_')
{
underscore_counter++;
printf("underscore_counter is %d \n", underscore_counter);
}
decrementor--;
}
}
}
return 0;
}
You can use strcspn() to find the first operator, which simplifies the problem a little. Then it's just a matter of going backwards and counting the underscores, and then just a matter of outputting the appropriate substrings, e.g.:
int main()
{
char str [] = "xa_55_y_*_z_/_+_x_+";
size_t firstOp = strcspn(str, "*/+-");
size_t len = strlen(str);
size_t i = firstOp;
int underscores = 0;
// go backwards looking for the underscores (or the beginning of the
// string, whichever occurs first)
while (i > 0)
{
if (str[--i] == '_')
underscores++;
if (underscores == 3)
break;
}
// output the first part of the string up to the third underscore
// before the first operator
for (size_t j = 0; j < i; j++)
putchar(str[j]);
// output the rest of the string after and including the operator
for (size_t j = firstOp; j < len; j++)
putchar(str[j]);
// and a linefeed character (optional)
putchar('\n');
}
Sorry for the poorly named i and j variables, hopefully it makes sense.