I have problem in program with locale and reading from stdin with fgetws function.
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
static const int N = 2;
int main(void) {
setlocale(LC_ALL, "");
wchar_t data[N];
fgetws(data, N, stdin);
printf("%ls\n", data);
/* fclose(stdin); */
return 0;
}
When input is long enough (5 or more chars) I get segfault if I don't close stdin before return. Why is that? What is wrong with this program?
Suspect fgetws(data, 2, stdin) is broken.
fgetws(), using such a small buffer should, at most, read 1 wchar_t from stdin and append a termanting (wchar_t) '\0'.
As usual, when code fails mysteriously, best to check return from the functions to see if they are as expected.
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <assert.h>
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
static const int N = 2;
int main(void) {
char *p = setlocale(LC_ALL, "");
assert(p);
wchar_t data[N];
wchar_t *s = fgetws(data, N, stdin);
assert(s);
int i = printf("%ls\n", data);
assert(i == 2);
i = fclose(stdin);
assert(i == 0);
return 0;
}
Related
I want to convert a Spanish string to uppercase. I use the function toupper for all characters. The function does not convert characters with accent:
PROTECCIóN
Nor the enye character:
DAñO
I use the setlocale function.
setlocale(LC_ALL, "es_ES");
It is possible to get the good result with setlocale(LC_ALL, "es_ES.utf8");, and use of wchar_t and of towupper(.) function.
Output
protección daño PROTECCIÓN DAÑO
#include <stdio.h>
#include <stdlib.h>
#include <wctype.h>
#include <wchar.h>
#include <locale.h>
int main(void) {
if (!setlocale(LC_ALL, "es_ES.utf8")) return 1;
wchar_t input[] = L"protección daño";
int length = sizeof(input)/sizeof(input[0]);
wchar_t output[length];
for (int i = 0; i < length-1; ++i) {
output[i] = towupper(input[i]);
}
output[length-1] = '\0';
printf ("%ls %ls\n", input, output);
return 0;
}
I am wondering why I need to alloc memory sometimes, to get an array with n size, but why I cannot instead of that using a pointer!
Look at this:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include "debug.h"
#include "memory.h"
char *getbuffer();
int main(void)
{
char *line;
line = getbuffer();
printf("First Char: %c\n", line[0]);
line[0] = 'g';
printf("Writed: %c\n", line[0]);
return 0;
}
char *getbuffer()
{
char *line;
size_t len = 0;
printf("String: ");
getline(&line, &len, stdin);
return line;
}
The above code works, And I dont to do something like this, but I think its not correct using only a pointer, instead of alloc memory, but I dont know why
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include "debug.h"
#include "memory.h"
char *getbuffer();
int main(void)
{
char *line;
char *buffer;
line = getbuffer();
printf("Foi isto que escrevi: %s\n", line);
buffer = malloc(strlen(line) * sizeof(char));
strcpy(buffer, line);
printf("Foi isto que escrevi: %c\n", buffer[0]);
printf("Tamanho Buffer: %ld\n", strlen(buffer));
return 0;
}
char *getbuffer()
{
char *line;
size_t len = 0;
printf("String: ");
getline(&line, &len, stdin);
return line;
}
So I am wondering, why I need to sometimes allocate memory to get the string or to save a string on an array instead of using always a pointer.
I am trying to read line by line a standard file input.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 1204
char* readLine(char* buffer){
int i = 0;
for(i; i< BUFFER_SIZE; i++){
printf("%c",buffer[i]);
if( '\n' == buffer[i]){
char* line[124];
memcpy( line, &buffer[0], i-1 );
return *line;
}
}
free(buffer);
}
int doStuffWithLine(char* line){
return 1;
}
int main(int argc, char *argv[])
{
ssize_t aux1;
char *buffer = malloc(sizeof(char)*BUFFER_SIZE);
char *line = malloc(sizeof(char)*BUFFER_SIZE);
while((read(STDIN_FILENO, buffer, BUFFER_SIZE))>0){
line = readLine(buffer);
doStuffWithLine(line);
printf("%s", line);
}
return 0;
}
This is the input file content:
lol1
lol2
lol3
And this is the output of my program:
lol1
Segmentation fault (core dumped)
I want to know how read lines 2 and 3, solve it and a little explanation about what I am doing wrong because I do not understand the problem.
Thank you in advance.
Function read reads in raw bytes and will not terminate your buffer with a string termination character '\0'; Using it then for printf("%s",...), which expects a 0-terminated C-string, yields undefined behaviour (e.g. a crash).
I'd suggest to use fgets instead.
First of all, thank you all that helped me and spent some time trying it.
After spending some hours learning and breaking my brain I have found a solution. In conclusion I am ***** and noob.
If someone is having the same problem I am submitting my code. Easy peasy:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
char* doStuff(char* line){
return line;
}
int main(int argc, char *argv[])
{
char *line = malloc(sizeof(char)*LINE_MAX);
while(fgets(line, LINE_MAX, stdin)!= NULL)
{
line = doStuff(line);
printf("%s", line);
}
return 0;
}
i am trying to insert a comma in a large integer number eg, 870120000 and present it as: 870,120 and the last three digits are discarded. The format will allways be the same, ie., xxxxxxxxx number where i am only interested in the first 6 digits.
What i have been doing so fare is using snprintf:
#include <stdio.h>
#include <string.h>
int main()
{
char buffer[5];
unsigned int lNum= 870120000;
int cx;
memset(buffer,0,sizeof(buffer));
cx = snprintf(buffer, 4, "%d,", lNum);
buffer[3] = ',';
printf("%s\n",buffer);
cx = snprintf(buffer+4, 4, "321"); // Note 1 ???
printf("%s\n", buffer);
return 0;
}
My problem is that i am stuck at (comment // Note 1), how do I add the last next three digits in to buffer ?
in addition I would like to know if this approch is ideal or is there any better(easier) way to do this?
You can do that in two steps. First convert the lNum into a string, then cut the needed parts out of this string. Something like that.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char tmp[256], out[256];
unsigned int lNum= 870120000;
sprintf(tmp, "%u", lNum);
sprintf(out, "%3.3s,%3.3s", tmp, tmp+3);
printf("%s\n", out); // prints 870,120
return 0;
}
See http://ideone.com/bnQNou
Or you can convert it into a float and change the locale to have "," as delimiter:
#include <stdio.h>
#include <locale.h>
int main()
{
unsigned int lNum = 870120000;
setlocale(LC_NUMERIC, "de_DE");
printf("%3.3f\n", (float)(870120000 / 1000000)); // prints 870,120
return 0;
}
First of all to hold 870,120 you have to define a 8 chars buffer.
So you can use %f format specifier to do what you the job, e.g.:
#include <stdio.h>
#include <string.h>
int main()
{
char buffer[8] = {0};
unsigned int lNum= 870120000;
snprintf(buffer, sizeof(buffer), "%3.3f", (float)(lNum)/(1000000));
char *temp = strstr(buffer, ".");
if (temp != NULL)
{
*temp = ',';
}
printf("%s\n",buffer);
return 0;
}
or another example using double snprintf and a given number of integer part digits and decimal part digits.
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define INT_DIGIT 3
#define DEC_DIGIT 3
int main()
{
char temp_buffer[128];
char buffer[INT_DIGIT+DEC_DIGIT+2] = {0};
unsigned int lNum= 87012000;
snprintf(temp_buffer, sizeof(temp_buffer), "%u",lNum);
snprintf(buffer, sizeof(buffer), "%.*s,%.*s", INT_DIGIT, temp_buffer, DEC_DIGIT, &temp_buffer[INT_DIGIT]);
printf("%s\n",buffer);
return 0;
}
I've got a problem reading a couple of lines from a read-only FIFO. In particular, I have to read two lines — a number n, followed by a \n and a string str — and my C program should write str in a write-only FIFO for n times. This is my attempt.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
char *readline(int fd);
int main(int argc, char** argv) {
int in = open(argv[1], O_RDONLY);
mkfifo(argv[2], 0666);
int out = open(argv[2] ,O_WRONLY);
char *line = (char *) malloc(50);
int n;
while (1) {
sscanf(readline(in), "%d", &n);
strcpy(line, readline(in));
int i;
for (i = 0; i < n; i++) {
write(out, line, strlen(line));
write(out, "\n", 1);
}
}
close(in);
close(out);
return 0;
}
char *readline(int fd) {
char *c = (char *) malloc(1);
char line[50];
while (read(fd, c, 1) != 0) {
if (strcmp(c, "\n") == 0) {
break;
}
strcat(line, c);
}
return line;
}
The code is working properly, but it puts a random number of newlines after the last string repetition. Also, this number changes at each execution.
Could someone please give me any help?
Besides the facts that reading character wise and and comparing two characters using "string" comparsion both is far from being efficient, readline() returns a pointer to memory being declared local to readline(), that is line[50] The memory gets deallocated as soon as readline() returns, so accessing it afterwards invokes undefine behaviour.
One possibility to fix this is to declare the buffer to read the line into outside readline() and pass a reference to it down like so:
char * readline(int fd, char * line, size_t size)
{
if ((NULL != line) && (0 < size))
{
char c = 0;
size_t i = 0;
while (read(fd, &c, 1) >0)
{
if ('\n' == c) or (size < i) {
break;
}
line[i] = c;
++i;
}
line [i] = 0;
}
return line;
}
And then call it like this:
char * readline(int fd, char * line, size_t size);
int main(void)
{
...
char line[50] = "";
...
... readline(in, line, sizeof(line) - 1) ...
I have not tried running your code, but in your readline function you have not terminated the line with null ('\0') character. once you hit '\n' character you just breaking the while loop and returning the string line. Try adding '\0' character before returning from the function readline.
Click here for more info.
Your code did not work on my machine, and I'd say you're lucky to get any meaningful results at all.
Here are some problems to consider:
readline returns a locally defined static char buffer (line), which will be destroyed when the function ends and the memory it once occupied will be free to be overwritten by other operations.
If line was not set to null bytes on allocation, strcat would treat its garbage values as characters, and could possibly try to write after its end.
You allocate a 1-byte buffer (c), I suspect, just because you need a char* in read. This is unnecessary (see the code below). What's worse, you do not deallocate it before readline exits, and so it leaks memory.
The while(1) loop would re-read the file and re-print it to the output fifo until the end of time.
You're using some "heavy artillery" - namely, strcat and memory allocation - where there are simpler approaches.
Last, some C standard versions may require that you declare all your variables before using them. See this question.
And here's how I modified your code. Note that, if the second line is longer than 50 characters, this code may also not behave well. There are techniques around the buffer limit, but I don't use any in this example:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
char *readline(int fd, char * buffer);
int main(int argc, char** argv) {
int in = open(argv[1], O_RDONLY);
int out;
int n;
int i;
char line[50];
memset(line, 0, 50);
mkfifo(argv[2], 0666);
out = open(argv[2] ,O_WRONLY);
sscanf(readline(in, line), "%d", &n);
strcpy(line, readline(in, line));
for (i = 0; i < n; i++) {
write(out, line, strlen(line));
write(out, "\n", 1);
}
close(in);
close(out);
return 0;
}
char *readline(int fd, char * buffer) {
char c;
int counter = 0;
while (read(fd, &c, 1) != 0) {
if (c == '\n') {
break;
}
buffer[counter++] = c;
}
return buffer;
}
This works on my box as you described. Compiled with GCC 4.8.2 .