I am reading a data from a method which returns 4 string values
printf(%s,%s,%s,%s \n",modValuex.A,modValuex.B,modValuex.C,modValuex.D)
it gives values like below but not in a single line like(12,-12,45 )
12
,-12
,45
1
,-23
119
how can i fix this/
I tried adding a \r and \t as well, same result.
This trimming of strings is best avoided, as commmented.
In C one possibility here would be to replace the first \n with a \0 in-place.
char* chop(char *s) {
char *p = s;
while (*p++)
if (*p == '\n') {
*p = '\0';
break;
}
return s;
}
called like this:
char s1[] = "12\n";
char s2[] = "13\n133\n1333\n";
char s3[] = "14\n";
printf("%s,%s,%s", chop(s1), chop(s2), s3);
it prints 12,13,14 and a newline.
The characters of s2 don't get printed. strlen(s2) is 2, but sizeof s2 is 13.
But that method (from which you read the data) should be a help, not a source of complication. (In C you rather assign a return value of a function)
modValuex.A and others contain a '\n'.
To print modValuex.A without a '\n' either remove it before printing or stop printing before the '\n'.
If possible, simply lop off the '\n':
modValuex.A[strcspn(modValuex.A, "\n")] = '\0';
If modValuex.A and friends unchangeable, to stop before the '\n', use a width limit:
// printf(%s,%s,%s,%s n",modValuex.A,modValuex.B,modValuex.C,modValuex.D)
printf(%.*s,%.*s,%.*s,%.*s\n",
(int) strcspn(modValuex.A, "\n"), modValuex.A,
(int) strcspn(modValuex.B, "\n"), modValuex.B,
(int) strcspn(modValuex.C, "\n"), modValuex.C,
(int) strcspn(modValuex.D, "\n"), modValuex.D);
size_t strcspn( const char *dest, const char *src )
returns the number of initial bytes in a string that are not in a second string.
Related
Hello I am doing a looping on my code with fgets and I want that when user introduces the word "bye" the program ends, so I have a do while like this:
char buf[1000]
do{
fgets(buf, 1000, stdin);
//More code here
while(strcmp(buf, "bye")!=0);
But I have a problem that it is, when user made a space or a tab or multiple spaces before write bye the strcmp doesnt recognize him as bye, so the program only exits when users only type bye without any previous space or tab.
I want to know how can I prevent the spaces or tabs before the by word to exits if user type for example:
' bye'
fgets reads in a complete line, including any starting white spaces and also including the new line character at the end of the line. Even if a user does not enter preceding white spaces, the content of buf is likely to be "bye\n", such that buf will hardly compare equal to "bye" when using strcmp.
I'd suggest to scan the buffer for a single word using sscanf and compare this word to "bye" then. Note that scanf("%s"...) skips white space characters at the beginning of a word and stops before the first white space after the word.
char isStopWord[20];
isStopWord[0] = '\0';
sscanf(buf,"%19s",isStopWord);
}
while(strcmp(isStopWord, "bye")!=0);
It a very strange requirement to use strcmp to remove characters from the array but everything is possible :)
char *removeSpacesAndTabsBeginning(char *str)
{
size_t len;
char savedc;
if(str && *str)
{
len = strlen(str);
savedc = str[1];
str[1] = 0;
while(!strcmp(str, " "))
{
str[1] = savedc;
memmove(str, str + 1, len);
savedc = str[1];
str[1] = 0;
}
str[1] = savedc;
}
return str;
}
int main(void)
{
char z[] = " \t\tHello World.";
printf("`%s`\n", removeSpacesAndTabsBeginning(z));
}
If you want to know if the string contains "bye" use strstr.
int isBye(const char *str)
{
return !!strstr(str, "bye");
}
There are 2 problems in your code:
you should test the return value of fgets() to detect unexpected end of file.
you should ignore whitespace in the comparison. You should just trim the string read by fgets() as the other code probably does not handle these either.
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main() {
char buf[1000];
while (fgets(buf, sizeof buf, stdin)) {
size_t i = 0, length = strlen(buf);
/* trim trailing white space */
while (length > 0 && isspace((unsigned char)buf[length - 1])) {
buf[--length] = '\0';
}
/* trim leading white space */
while (isspace((unsigned char)buf[i]) {
i++;
}
if (i > 0) {
memmove(buf, buf + i, length - i + 1);
}
// check for end command
if (!strcmp(buf, "bye"))
break;
//More code here: handle other commands
//...
}
return 0;
}
I have some C code to print a string char array twice.
Code:
char* twice(char *s) {
int size=strlen(s),i=0;
int length=size*2;
char check = s[size-1];
char* s2 = malloc(length * sizeof(char));
char* reset = malloc(size * sizeof(char));
memcpy(reset, s, size * sizeof(char));
while (i<length) {
printf("%s\n", s);
s2[i] = *s;
if(s2[i] == check && i == size-1){
s = reset;
}else s++;
i++;
}
return s2;
}
int main(){
char s[] = "hello1234";
printf("%s\n", twice(s));
return 0;
}
Output:
hello1234
ello1234
llo1234
lo1234
o1234
1234
234
34
4
hello1234
ello1234
llo1234
lo1234
o1234
1234
234
34
4
hello1234hello1234Ms?
The inputted string is hello1234 and i am printing out each pointer to show that it correctly runs through the string twice. But for some reason the answer includes Ms? resulting in hello1234hello1234Ms? why is that?
In C, strings are terminated with a special character with the value '\0'.
memcpy() works with memory, it is not specific to strings. And so it does not copy the terminator since you didn't give it a length that includes the terminator. (strlen() does not include the terminator.)
When printf() doesn't find the terminator, it just keeps printing whatever is in memory. The additional characters are just random and will be different on different set ups.
Is there any efficient (- in terms of performance) way for printing some arbitrary string, but only until the first new line character in it (excluding the new line character) ?
Example:
char *string = "Hello\nWorld\n";
printf(foo(string + 6));
Output:
World
If you are concerned about performance this might help (untested code):
void MyPrint(const char *str)
{
int len = strlen(str) + 1;
char *temp = alloca(len);
int i;
for (i = 0; i < len; i++)
{
char ch = str[i];
if (ch == '\n')
break;
temp[i] = ch;
}
temp[i] = 0;
puts(temp);
}
strlen is fast, alloca is fast, copying the string up to the first \n is fast, puts is faster than printf but is is most likely far slower than all three operations mentioned before together.
size_t writetodelim(char const *in, int delim)
{
char *end = strchr(in, delim);
if (!end)
return 0;
return fwrite(in, 1, end - in, stdout);
}
This can be generalized somewhat (pass the FILE* to the function), but it's already flexible enough to terminate the output on any chosen delimiter, including '\n'.
Warning: Do not use printf without format specifier to print a variable string (or from a variable pointer). Use puts instead or "%s", string.
C strings are terminated by '\0' (NUL), not by newline. So, the functions print until the NUL terminator.
You can, however, use your own loop with putchar. If that is any performance penalty is to be tested. Normally printf does much the same in the library and might be even slower, as it has to care for more additional constraints, so your own loop might very well be even faster.
for ( char *sp = string + 6 ; *sp != '\0'; sp++ ) {
if ( *sp == '\n' ) break; // newline will not be printed
putchar(*sp);
}
(Move the if-line to the end of the loop if you want newline to be printed.)
An alternative would be to limit the length of the string to print, but that would require finding the next newline before calling printf.
I don't know if it is fast enough, but there is a way to build a string containing the source string up to a new line character only involving one standard function.
char *string = "Hello\nWorld\nI love C"; // Example of your string
static char newstr [256]; // String large enough to contain the result string, fulled with \0s or NULL-terimated
sscanf(string + 6, "%s", newstr); // sscanf will ignore whitespaces
sprintf(newstr); // printing the string
I guess there is no more efficient way than simply looping over your string until you find the first \n in it. As Olaf mentioned it, a string in C ends with a terminating \0 so if you want to use printf to print the string you need to make sure it contains the terminating \0 or yu could use putchar to print the string character by character.
If you want to provide a function creating a string up to the first found new line you could do something like that:
#include <stdio.h>
#include <string.h>
#define MAX 256
void foo(const char* string, char *ret)
{
int len = (strlen(string) < MAX) ? (int) strlen(string) : MAX;
int i = 0;
for (i = 0; i < len - 1; i++)
{
if (string[i] == '\n') break;
ret[i] = string[i];
}
ret[i + 1] = '\0';
}
int main()
{
const char* string = "Hello\nWorld\n";
char ret[MAX];
foo(string, ret);
printf("%s\n", ret);
foo(string+6, ret);
printf("%s\n", ret);
}
This will print
Hello
World
Another fast way (if the new line character is truly unwanted)
Simply:
*strchr(string, '\n') = '\0';
The program I am writing needs to remove an ampersand character if it is the last character of a string. For instance, if char* str contains "firefox&", then I need to remove the ampersand so that str contains "firefox". Does anyone know how to do this?
Just set the last char to be '\0':
str[strlen(str)-1] = '\0';
In C, \0 indicates a string ending.
Every string in C ends with '\0'. So you need do this:
int size = strlen(my_str); //Total size of string
my_str[size-1] = '\0';
This way, you remove the last char.
To be on the safe side:
if (str != NULL)
{
const unsigned int length = strlen(str);
if ((length > 0) && (str[length-1] == '&')) str[length-1] = '\0';
}
Just for reference, the standard function strchr does just that. It effectively splits the string on a given set of characters. It works by substituting a character with 0x00
Example shamelessly stolen from: cplusplus.com
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a firefox& string";
char * pch;
printf ("Looking for the '&' character in \"%s\"...\n",str);
pch=strchr(str,'&');
while (pch!=NULL)
{
printf ("found at %d\n",pch-str+1);
pch=strchr(pch+1,'&');
}
return 0;
}
Check the last character and if it is '&', replace it with '\0' (null terminator):
int size = strlen(my_str);
if (str[size - 1] == '&')
str[size - 1] = '\0';
I want to delete a Newline '\n' within a string.
char *string ="hallo\n";
int i=0;
int length = sizeof(string);
while(i<length)
{
if(string[i+1] == '\n')
{
string[i+1] = '\0';
break;
}
i++;
}
printf("%s",string);
printf("world");
I know that I could just spawn a new array and it works like this
char *string ="hallo\n";
int i=0;
int length = sizeof(string);
int lengthNew = length -1;
char newStr[lengthNew];
while(i<length)
{
printf("Char ist %c:",string[i]);
newStr[i] = string[i];
if(string[i+1] == '\n')
break;
i++;
}
But why using stack if I just could substitude one character in the old array?
Based on your comment, I offer a completely different, yet better solution: strftime:
time_t clock = time(NULL);
char buf[1024];
strftime(buf, sizeof buf, "%c", localtime(&clock);
printf("The date is: %s\n", buf);
The %c format is the same as is used by ctime, but strftime is more flexible.
If the newline is always the last character of the string, you could code it like you have described.
Otherwise you'd have to create a second character buffer and copy the characters to the second buffer. The reason for this is that in C the \0 character marks the end of the string.
If you have a string like this: "this \n is \n a \n test", then after your replacement the memory would look like this: "this \0 is \0 a \0 test". Most C programs will simply interpret this as the string "this " and ignore everything after the first null.
EDIT
As other have pointed out, there are also other problems with your code. sizeof() will return the size of the character pointer, not the length of the string. It is also not possible to modify a readonly string literal.
char *string = ctime(&myTimeT);
char *c = strrchr(string, '\n');
if (c != NULL)
*(c) = '\0';