I am trying to print something on the console just by using the syscall write(). So far, it is more difficult than I thought.
The function is kept simple:
void writeOutput(char a, int64_t b, uint8_t c) {
char bNew[]; // what should be the size of that array=
while(b != 0x0000000000000000) {
int leftover = b%10;
bNew[i] = intToChar(leftover);
b = b/10;
i++;
}
}
char intToChar(int num) {
return '0' + num;
}
a should be formatted as char, b as a decimal number and c as an octal number.
For example a possible input is:
writeOutput('a', -0xffff, 17); // ouput is "a -65535 21"
The the printed arguments should be separated by spaces and terminated by a newline to standard output. Also, I am trying to do that without the the functions of the sprintf-family. This makes it a little bit trickier.
EDIT: My question is: How is it possible to do that with write()? (Sry, missed that!)
The code is online.
EDIT2: My main problem is doing it without using the sprintf-family. I hoped you might help me.
you can call the write() with first argument which is an fd as stdout. it will write to the stdout and which is your console. but before that you need have a string buffer for that you can use sprintf' orsnprintfwith the same formatting asprintf`. but the printf way is easier and it should serve the purpose unless you have some very special use case.
#include <unistd.h>
int main(void) {
write(1,"Hello World!", 12);
return 0;
}
Related
Doing my best to be brief; I am trying to program an LCD to print out an integer variable (of more than 1 digit). I'm trying to do this using the itoa function as the LCD takes ASCII characters. The below code compiles and prints "Set Temp: " when I want it to, the problem is that it doesn't print out the chars (digits) stored in the numberString array like I want it to. The writeString function is working fine but I cant figure out why it's just not printing the value of int setTemp after "Set Temp: ". All that's outputted is: "Set Temp: " with the cursor just hanging.
Probably worth mentioning that the cursor is hanging ON the position where the value should be printed on the LCD, indicating that it isn't just printing an empty value, it just isn't printing anything at all or waiting for something.
Apologies for any incorrect formatting of question, I'm new.
void writeChar(unsigned char ch)
{
lcd = ch;
RS = 1;
RW =0;
E = 1;
lcdDelay();
E=0;
}
void writeString(char *stringToLcd)
{
while(*stringToLcd > 0)
{
writeChar(*stringToLcd++);
}
}
int changeTriggTemp(void)
{
char numberString[4]; //buffer, -99 -> 99
int setTemp = 50;
clearDisplay();
writeString("Set Temp: ");
itoa(setTemp,numberString,10);
lcdDelay();
writeString(numberString);
while(1); //placeholder before I return the int I want
}
If you don't define a function prototype, the compiler can make incorrect assumptions about it, and code its use wrongly. Having drawn your attention to that I asked what the definition is, because the usual definition (at least in MSVC) is
char *itoa(int value, char *str, int radix);
This agreed with your own usage of the function,
itoa(setTemp, numberString, 10);
however on closer inspection of your library header file, you stated that it defines
itoa(char * buf, int val, int base);
In other words, the first two arguments are switched. Since itoa() is not a standard function, this is allowed, but you have to call it accordingly:
itoa(numberString, setTemp, 10);
(Thanks to #Eric whose suggestions revealed that it could well be itoa at fault).
Is it possible to print out (in C) a line of text to the console on a Linux OS containing a variable so that when the variable changes, it changes the printed line instead of printing a new line? For example, if I have the following C code:
void main()
{
int i;
for(i=1;i<=10;i++){
printf("%d\n",i);
sleep(5);
}
}
As is, that would print ten lines. But I want to print one line that updates itself to show the value of i when it changes.
On Linux, void main(void) is undefined behaviour; the return type is int — no exceptions. On Windows, the rules are different; on Unix, they're simple — main() returns int!
Use '\r' carriage return and fflush():
#include <stdio.h>
int main(void)
{
int i;
for (i = 1; i <= 10; i++)
{
printf("\r%d", i);
fflush(stdout);
sleep(5);
}
putchar('\n');
return 0;
}
No need to use the curses library unless your display needs get more complex.
Note: if you are counting down (or the length of the current row of output decreases for any reason), you need to make sure you write blanks over previously displayed data. So, for example, you might need the format string "\r%-4d" to count from 9999 to 0 without leaving unwanted digits on display.
Something like the following should do the job (taken / modified from How to update a printed message in terminal without reprinting (Linux))
int main(int argc, char *argv[]) {
for(int i=1;i<=10;++i) {
printf("\r[%3d%%]",i);
fflush(0);
sleep(5);
}
printf("\n");
}
Not exactly sure what you are up to, but maybe writing the content of your variable into a temporary file and using watch(1) to visualize it is an option?
So I am a very beginner to C programming (I have used Ruby, Python and Haskell before) and I am having trouble getting the most simple thing to work in C (probably because of all the manual memory stuff). Anyway, what I am trying to do is (using simple constructs) make a script that just echoes what the user inputs to the console.
e.g. user inputs hi, console prints hi.
This is what I came up with.
Also, I haven't really mastered pointers, so none of that.
// echo C script
int echo();
int main() {
echo();
return 0;
}
int echo() {
char input[500];
while (1) {
if (scanf("%[^\n]", input) > 0) {
printf("%s\n", input);
}
input[0] = 0;
}
return 1;
}
I realize that there is a bunch of bad practices here, like setting a giant string array, but that is just for simplifying it.
Anyway, my problem is that it repeats the first input then the input freezes. As far as I can tell, it freezes during the while loop (1 is never returned).
Any help would be appreciated.
Oh, and using TCC as the compiler.
You don't need an array for echo
#include <stdio.h>
int main(void)
{
int c;
while((c = getchar()) != EOF) putchar(c);
return 0;
}
It's fine that you have such a large string allocated, as long as it's possible for users to input a string of that length. What I would use for input is fgets (read this for more information). Proper usage in your situation, given that you still would like to use the string of size 500, would be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int echo(){
char input[500];
while(fgets(input, 500, STDIN)){ //read from STDIN (aka command-line)
printf("%s\n", input); //print out what user typed in
memset(input, 0, strlen(input)); //reset string to all 0's
}
return 1;
}
Note that changing the value of 500 to whatever smaller number (I would normally go with some power of 2 by convention, like 512, but it doesn't really matter) will limit the length of the user's input to that number. Also note that I didn't test my code but it should work.
scanf("%[^\n]", input
Should be:
scanf("%s",input)
Then after your if you should do:
memset(input,0,500);
There are many ways of accomplishing this task however the easiest would be to read from stdin one byte at a time and output that byte to stdout as you process each byte.
Snippet:
#include <stdio.h>
int main( void ) {
// Iterates until EOF is sent.
for ( int byte = getchar(); byte != EOF; byte = getchar() ) {
// Outputs to stdout the byte.
putchar( byte );
}
return 0;
}
Remark:
You must store the byte that you are reading through stdin in an integer. This is because you are not guaranteed that char is signed or unsigned, there are in fact 3 char types in C (char, signed char and unsigned char). Include the limits library to determine whether a char is signed or not in your environment.
You must compile using the C99 standards, otherwise move the declaration of byte outside of the for loop.
I've been trying to write a function in C that detects palindromes. The program currently looks like the following:
#include <stdio.h>
#include <string.h>
int main()
{
char palindrome[24]; int palength; int halflength;
gets(palindrome);
palength = strlen(palindrome);
halflength = palength / 2;
printf("That string is %u characters long.\r\n", palength);
printf("Half of that is %u.\r\n", halflength);
return 0;
}
Right now it detects the length of a string, and also shows what half of that is. This is just to make sure it is working how I think it should be. What the rest of the function should do (if possible) is take the integer from "halflength" and use that to take that amount of characters off of the beginning and end of the string and store those in separate strings. From there I'd be able to compare the characters in those, and be able return true or false if the string is indeed a palindrome.
TL;DR - Is it possible take a certain amount of characters (in this case the integer "halflength") off the front and end of a string and store them in separate variables. Read above for more information on what I'm trying to do.
P.S. - I know not to use gets(), but didn't feel like writing a function to truncate \n off of fgets().
int len = strlen(palindrome) - 1; // assuming no \n
int half = len << 1;
for (int i=0; i<=half; ++i)
if(palindrome[i] != palindrome[len-i])
return false;
return true;
What if you do something like this,
char *str1="lol",*str2;
str2=strrev(str1);
//if both are same then it actually is a palindrome ; )
Found out I was approaching the problem wrong. How I should be doing this is iterating over the characters using a pointer both backwards and forwards. Although if you'd still like to answer the original question it could still be useful at some point.
Now this is a silly puzzle I got from some exam paper,sadly I am unable to figure it out from last 15 minutes.
#include <stdio.h>
int main(void){
/* <something> */
putchar(*(wer[1]+1));
return 0;
}
What should we replace in place of something in order to get the output e.Now we know putchar takes a int as argument but this code assumes to give a pointer.Does this question is even valid ?
const char *wer[2] = { "failed", "test" };
Since a[i] is the same as *(a + i) by definition, you can transform the putchar() argument into wer[1][1]. So, something like char *wer[2] would be a satisfactory definition, and any values such that wer[1][1] == 'e' will work.
char * wer[] = { "foobar", "he"};
First, in the code you have mentioned the argument to putchar() is
*(wer[1]+1)
which is not a pointer. It seems that wer[1] is some pointer and that address pointed by wer[1] + 1 is dereferenced. So if wer is an array of pointers to int, then putchar argument should be int which is fine.
Now the code in place of something can be
You have not mentioned clearly what does e mean, is e a char or e is 2.71... (Natural logarithm base) In either case it should be easy to get that output with this code.
-AD
An easy answer is:
char **wer;
putchar('e');
return 0;
For example, the complete code would like like:
#include <stdio.h>
int main(int argc, char **argv)
{
/* Something starts here */
char **wer;
putchar('e');
return 0;
/* Something ends here */
putchar(*(wer[1] + 1));
return 0;
}
The output is:
susam#swift:~$ gcc really-silly-puzzle.c && ./a.out && echo
e
susam#swift:~$
A more interesting question would have been: What is the shortest code that can replace /* */ to get the output 'e'?
From the very pedantic point of view, there's no correct answer to the question. The question is invalid. C language itself makes no guarantees about the output of a program if the output does not end in a newline character. See 7.19.2/2
A text stream is an ordered sequence
of characters composed into lines,
each line consisting of zero or more
characters plus a terminating new-line
character. Whether the last line
requires a terminating new-line
character is implementation-defined.
This program output to the standard output, which is a text stream. The output of this program is implementation-dependent, regardless of what you put in place of /* <something> */, meaning that the question might make sense for some specific platform, but it makes no sense as an abstract C language question.
I highly doubt though that your examiners are expecting this kind of pedantry from you :)))