Print a string of a given length - c

printf("%s", ...) assumes null-terminated string. If I have a string deliminated by a length, what is the best way to do?
Suppose buf is the start address of the string, n is the length of the string. I have the following code. Is it the best way to do so?
for(int i=0;i<n;++i) {
fputc(buf[i], stdout);
}

You can use %.*s format specifier to specify the length to print.
#include <stdio.h>
int main(void) {
int length = 3;
const char* str = "123456";
printf("%.*s\n", length, str);
return 0;
}
This example will print 123.
Better way to print fixed-length data should be using fwrite(). printf() can do many thing, so it may be unnecessarily slow.
#include <stdio.h>
int main(void) {
int length = 3;
const char* str = "123456";
fwrite(str, sizeof(*str), length, stdout);
return 0;
}

I think using fwrite is also an overkill here a you are anyway printing a string (which is a set of char).
Instead you could just use putchar(), it writes to stdio by default.
while(i<n)
putchar(buf[i++]);

Related

How to check char * "length" before I use string functions in C?

I want to check C string length and if it is valid (\0 termination).
So far I have this:
#include <stdio.h>
char good_str[32] = "123456789012345"; // 15 chars with `\0` is ok
char bad_str[32] = "1234567890123456"; // 16 chars with `\0` is too long
int check_max_len(char * s, int max_len){
for (int i = 0; i < max_len; i++) {
if (s[i] == 0)
return 0; // not too long
}
return 1; // too long or no `\0`
}
int main() {
int is_bad;
is_bad = check_max_len((char*)&good_str, 16);
printf("Good string: %i\n", is_bad);
is_bad = check_max_len((char*)&bad_str, 16);
printf("Bad string: %i\n", is_bad);
return 0;
}
I guess this will work well for my application, but maybe there are some "industry standards", or some function in standard library for that?
There is a standard function strnlen() from the string.h header file which comes fairly close to functionality you are looking for. It takes 2 parameters: a string (const char*) and a maximum read length (size_t) respectively.
It looks like this:
size_t strnlen(const char* str, size_t max_len);
It will return the quantity of bytes pointed to by the passed string, excluding the terminating null character if encountered within the the passed max_len.
Logically speaking, this function still requires you to know the expected string length so that way you can have an accurate results. Without that information, your program will error out or it will do unexpected things such as reading into other strings, and data. Hence why you should make it clear that you expect null terminated strings to begin with.

Need help creating a function that returns the size of the string you type in

So the practice problem I'm doing asks to write a complete C program that inputs the line of text from the keyboard and calculates the size of the entered string. Your program should use a function stringLength()which calculates and returns the size of the given string. Function has the following prototype:size_t stringLength(const char* sPtr);
The following is what I have but I'm still learning the ropes as I'm going. I'm assuming it's asking to implement pointers as well and I'm very crusty when it comes to pointers. The function is basically where I'm stuck at, any tips or pointers?
#include <stdio.h>
// prototype
size_t stringLength(const char* sPtr) {
int* str = &sPtr;
return sizeof(str);
}
int main() {
char* s[100]; //input string
puts("Enter a string");
fgets(s, 99, stdin);
printf("According to stringLength, the length is: %d\n", stringLength(&s));
return 0;
}
You should use array of char, not array of char*, to store strings.
sizeof is for determining size of types. You should use strlen() to determine length of strings.
After fixing the type of s, Pass s, not &s, to stringLength to match the data type with the argument.
%d is for printing int. You should use %zu to print size_t.
Try this:
#include <stdio.h>
#include <string.h>
// prototype
size_t stringLength(const char* sPtr) {
return strlen(sPtr);
}
int main() {
char s[100]; //input string
puts("Enter a string");
fgets(s, 99, stdin);
printf("According to stringLength, the length is: %zu\n", stringLength(s));
return 0;
}

sscanf get string until second symbol (include one)

How to get string until second symbol through sscanf?
for example:
char *str = "struct1.struct2.struct3.int";
char buf[256] = {0};
sscanf(str, "", buf); //have any format string could get string until second dot?
sscanf get string until second symbol (include one)
How to get string until second symbol through sscanf?
Not generally possible with a single use of sscanf().
Certainly, without a lot of work, a more involved use of sscanf() will work for many input strings, yet fail for select ones1. sscanf() is not the best fit here for this task.
strchr(), strcspn() better suited.
#include <string.h>
#include<stdlib.h>
// Return offset to 2nd needle occurrence
// or end of string, if not found.
size_t foo(const char *haystack, const char *needle) {
size_t offset = strcspn(haystack, needle);
if (haystack[offset]) {
offset++;
offset += strcspn(haystack + offset, needle);
}
return offset;
}
#include <stdio.h>
int main() {
const char *haystack = "struct1.struct2.struct3.int";
printf("<%.*s>\n", (int) foo(haystack, "."), haystack);
}
Output
<struct1.struct2>
1 Consider: "struct1.struct2", "struct1..", "..struct2", ".struct2.", "..", ".", "".
You can use a * to tell scanf to ignore an element:
const char *str = "struct1.struct2.struct3.int";
int main() {
char buf[256];
int i = sscanf(str, "%*[^.].%[^.]", buf);
printf("%d >%s<\n", i, buf);
return 0;
}
This outputs as expected:
1 >struct2<
because exactly 1 element was assigned even if another one was parsed.

Copy a string into another without \0

I have to put a string into another without \0, I tryed a lot of ways but the string is always dirty.
char string[100];
int pos=0;
fgets(string, 99, stdin);
len = strlen(string);
printf("%d\n", len);
char array[len-1];
for(pos=0; pos<(len-1); pos++)
{
array[j]=string[pos];
j++;
}
printf("%s", string);
printf("%s", array);
In the terminal I have:
dogs dogs(ENTER)
10(ENTER)
dogs dogs(ENTER)
dogs dogs#
I also tryed to remove \0 using another symbol but it can't see '\0' or '\n', help me plz!
Passing pointer to what is not a null-terminated string to %s without length specification will invoke undefined behavior. You have to specify the length to print if you hate terminating null-character for some reason.
Try this:
#include <stdio.h>
#include <string.h>
int main(void) {
int len;
char string[100];
int pos=0;
fgets(string, 99, stdin);
len = strlen(string);
printf("%d\n", len);
char array[len];
for(pos=0; pos<len; pos++)
{
array[pos]=string[pos];
}
printf("%s", string);
printf("%*s", len, array);
return 0;
}
TL;DR You don't want null-terminator, fine. Along with that you should be ready to give up those properties, which comes with the presence of null-terminator. You can no longer make use of the array as string.
To elaborate, in your code, your array array is not null-terminated, so it cannot be used as a string. the %s format specifier expects a pointer to the null-terminated char array (in short, a string)
So, in your code,
printf("%s", array);
invokes undefined behavior by going past the allocated memory in search of the null-terminator.
You can however, print it element by element using a for loop.
To copy without the terminating null, use
memcpy( myCharArray, string, strlen(string) );
(assumes size of myCharArray is sucfficient). To print out the result, you need to use a loop instead of printf.

Is there any function to get an unlimited input string from standard input

The condition is:
I want to input a line from standard input, and I don't know the size of it, maybe very long.
method like scanf, getsneed to know the max length you may input, so that your input size is less than your buffer size.
So Is there any good ways to handle it?
Answer must be only in C, not C++, so c++ string is not what I want. I want is C standard string, something like char* and end with '\0'.
The C standard doesn't define such a function, but POSIX does.
The getline function, documented here (or by typing man getline if you're on a UNIX-like system) does what you're asking for.
It may not be available on non-POSIX systems (such as MS Windows).
A small program that demonstrates its usage:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *line = NULL;
size_t n = 0;
ssize_t result = getline(&line, &n, stdin);
printf("result = %zd, n = %zu, line = \"%s\"\n", result, n, line);
free(line);
}
As with fgets, the '\n' newline character is left in the array.
One way is to run a loop with getchar and keep placing the characters into an array. Once the array is full, reallocate it to a larger size.
There is an often overlooked conversion specification within scanf that will allocate memory sufficient to hold the string input regardless of length. Newer versions of scanf use m for this purpose. Older versions used a. For example:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *str = NULL;
printf (" enter a string of any length, whitespace is OK: ");
scanf ("%m[^\n]%*c", &str);
printf ("\n str: %s\n\n", str);
if (str) free (str);
return 0;
}
Note: scanf requires a char ** pointer argument to receive the allocated string. Also note scanf does not include the '\n' in the stored string. Further note the %*c which receives and discards the '\n' character to prevent the newline from remaining in the input buffer. You may also precede the conversion specifier with whitespace to skip any/all whitepace that may exist in the input buffer.
Lastly Note: there are reports that not all implementations of scanf offer this feature. (which may also be confusion of the m/a change) Check your implementation.
One of the method is using getchar() function we can get input in a character and transfer it to dynamicall created array. You can see that when it exceeds the default length set by us, we reallocated space for storing character
#include<stdio.h>
#include<stdlib.h>
void main(){
int size = 10;
char* str;
str = (char*) calloc(size,sizeof(char));
char c;
c = getchar();
int t = 0;
int cnt = 0;
int len;
while(c!='\n') {
if(cnt > size) {
str = (char*) realloc(str,2*cnt);
}
str[t] = c;
c = getchar();
t++;
cnt++;
}
str[t]='\0';
printf("The string is %s\n",str);
len = strlen(str);
printf("The size is %d",len);
}
use getchar, malloc and realloc for reading the unlimited input string
Declare String type, you can also use char *
// String type
typedef char *String;
I write this function for joining the char in the end of string
/**
* Join the Char into end of String
*
* #param string - String
* #param c - joined char
*/
void String_joinChar(String *string, const char c)
{
const size_t length = strlen(*string);
(*string) = (String)realloc((*string), sizeof(char) * (length + 2));
(*string)[length] = c;
(*string)[length + 1] = '\0';
}
This function for inputting string, which read the char from keyboard by using getchar and join it in the end of current string.
/**
* Input String
*
* #return Inputed String
*/
String String_input()
{
String string = (String)malloc(sizeof(char));
strcpy(string, "");
char cursor;
fflush(stdin);
while ((cursor = getchar()) != '\n' && cursor != EOF)
{
String_joinChar(&string, cursor);
}
return string;
}
Cause of using char *, malloc and realloc, we must free it
/**
* Destroy String
*
* #param string - Destroyed String
*/
void String_destroy(String string)
{
free(string);
}
And now we just use it !!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
String string = String_input();
printf("\n%s\n", string);
String_destroy(string);
return 0;
}
Hope useful to you!

Resources