遍历存储在数组中的字符串中的每个字符
Iterate through every char in string stored in an array
我对C真的很陌生,在大学的前半年。这是我在 Whosebug 上的第一个问题。
我的任务是对其进行编程,以便将存储在数字中的每个字符串都转换为小数,而不更改主函数之外的任何内容。
我现在正在尝试过去 4 个小时来解决这个问题,我想遍历我当前所在的字符串中的每个字符,基于与长度相比的位置,将其转换为十进制。
我唯一的问题是有人帮助我理解如何在不使用 strlen()
的情况下获取字符串长度,因为我无法添加 #include <string.h>
这是我到目前为止得到的(获取数组的长度以遍历每个索引):
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
// Add here..
int length = sizeof(numbers);
for ( int i = 0; i < length; i++ ){
//how do i get the string size without strlen() D:
}
return 0;
}
有几种方法可以做到。 IMO,实现 strlen
的一种简单、合理的方法是:
size_t string_length(const char *s) { return strchr(s, '[=10=]') - s; }
但是如果您不被允许使用 strlen
那么您可能也不被允许使用 strchr
。所以你只需要数数。对于初学者来说,最惯用的方法可能有点晦涩难懂,所以这里有一个更详细的方法。
请注意,您对数组中元素数量的计算无效,已在下方更正。
#include <stdio.h>
int
length(const char *s)
{
int len = 0;
while( *s++ ){
len += 1;
}
return len;
}
int
main(void)
{
char *numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"
};
int count = sizeof numbers / sizeof *numbers; /* Number of entries */
for( int i = 0; i < count; i++ ){
printf(" length of %s is %d\n", numbers[i], length(numbers[i]));
}
return 0;
}
这很主观,但我认为更惯用的写法是:
#include <stdio.h>
int
length(const char *e)
{
const char *s = e;
while( *e++ )
;
return e - s - 1;
}
int
main(void)
{
char *numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"
};
char **e = numbers + sizeof numbers / sizeof *numbers;
for( char **t = numbers; t < e; t++ ){
printf(" length of %s is %d\n", *t, length(*t));
}
return 0;
}
#include <stdio.h>
int main(){
char arr[20]="Hello";
int count=0;
while(arr[count]!='[=10=]'){
count++;
}
printf("%d",count);
return 0;
}
看看这段小代码,你就明白了。在 C 中,字符串以 NULL 字符结尾。我们可以利用这个优势。
这个项目可以在不计算字符串长度的情况下完成。如何?在 C 中,所有字符串都是 nul-terminated 包含 nul-character '[=12=]'
(ASCII 值 0
)构成字符串的最后一个字符。当您需要遍历一个字符串时,您只需循环直到字符值为 0
(例如 nul-character)
这就是所有字符串函数知道何时停止读取字符的方式。由于您有一个包含字符串的 array-of-pointers ,因此您只需要遍历每个指针并为每个指针遍历每个字符,直到找到 nul 字符。
总而言之,(并指出您不需要 math.h
),您可以:
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
int nnumbers = sizeof numbers / sizeof *numbers; /* no. of elements */
for (int i = 0; i < nnumbers; i++) {
long long unsigned number = 0;
/* you don't care about the length, strings are nul-terminated,
* just loop until [=10=] is found.
*/
for (int j = 0; numbers[i][j]; j++) {
number <<= 1; /* shift left */
number += numbers[i][j] == '1' ? 1 : 0; /* add bit */
}
printf ("%s = %llu\n", numbers[i], number); /* output result */
}
return 0;
}
(注意: 您必须使用 64 位类型来保存转换后的值,因为 "1010110011010101111101111010101110110"
至少需要 38
位来表示)
例子Use/Output
将每个字符串转换为数值的简单示例输出:
$ ./bin/binstr2num
01001001 = 73
00101010 = 42
010100111001 = 1337
011111110100101010010111 = 8342167
0001010110011010101111101111010101110110 = 92790519158
01011100110000001101 = 379917
在 C 中,字符串实际上只是 char
数组,带有一个特殊的终止符来标记字符串的结尾。所以,假设你有这样的东西:
char *str = "hello";
这基本上等同于:
char str[] = {'h', 'e', 'l', 'l', 'o', '[=11=]'};
注意到数组末尾的 [=17=]
字符了吗?这是 C 放在字符串末尾的特殊终止符。像 strlen()
这样的函数几乎遍历 char
数组寻找第一次出现的 [=17=]
字符然后停止。
因此,您可以制作自己的 strlen()
版本,像这样说 my_strlen()
:
int my_strlen(char *str)
{
/* Initialize len to 0 */
int len = 0;
/* Iterate through str, increment len, and stop when we reach '[=12=]' */
while(str[len] != '[=12=]')
len++;
/* Return the len */
return len;
}
然后在你的 for
循环中,你可以调用这个函数。另外,请注意您对 numbers
数组大小的计算:
int length = sizeof(numbers);
不会给你数组中元素的数量。该代码为您提供大小(以字节为单位)或 numbers
,这是一个 char
指针数组。如果您想获得元素的数量,则必须将该大小除以单个元素(即 char
指针)的大小(以字节为单位)。所以,这样的事情会起作用:
int length = sizeof(numbers) / sizeof(numbers[0]);
您的最终代码可能如下所示:
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int my_strlen(char *str) {
/* Initialize len to 0 */
int len = 0;
/* Iterate through str, increment len, and stop when we reach '[=15=]' */
while(str[len] != '[=15=]')
len++;
/* Return the len */
return len;
}
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
// Add here..
// Notice the change here
int length = sizeof(numbers) / sizeof(numbers[0]);
for(int i = 0; i < length; i++ ){
int str_len = my_strlen(numbers[i]);
// Do what you need with str_len
}
return 0;
}
我对C真的很陌生,在大学的前半年。这是我在 Whosebug 上的第一个问题。
我的任务是对其进行编程,以便将存储在数字中的每个字符串都转换为小数,而不更改主函数之外的任何内容。
我现在正在尝试过去 4 个小时来解决这个问题,我想遍历我当前所在的字符串中的每个字符,基于与长度相比的位置,将其转换为十进制。
我唯一的问题是有人帮助我理解如何在不使用 strlen()
的情况下获取字符串长度,因为我无法添加 #include <string.h>
这是我到目前为止得到的(获取数组的长度以遍历每个索引):
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
// Add here..
int length = sizeof(numbers);
for ( int i = 0; i < length; i++ ){
//how do i get the string size without strlen() D:
}
return 0;
}
有几种方法可以做到。 IMO,实现 strlen
的一种简单、合理的方法是:
size_t string_length(const char *s) { return strchr(s, '[=10=]') - s; }
但是如果您不被允许使用 strlen
那么您可能也不被允许使用 strchr
。所以你只需要数数。对于初学者来说,最惯用的方法可能有点晦涩难懂,所以这里有一个更详细的方法。
请注意,您对数组中元素数量的计算无效,已在下方更正。
#include <stdio.h>
int
length(const char *s)
{
int len = 0;
while( *s++ ){
len += 1;
}
return len;
}
int
main(void)
{
char *numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"
};
int count = sizeof numbers / sizeof *numbers; /* Number of entries */
for( int i = 0; i < count; i++ ){
printf(" length of %s is %d\n", numbers[i], length(numbers[i]));
}
return 0;
}
这很主观,但我认为更惯用的写法是:
#include <stdio.h>
int
length(const char *e)
{
const char *s = e;
while( *e++ )
;
return e - s - 1;
}
int
main(void)
{
char *numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"
};
char **e = numbers + sizeof numbers / sizeof *numbers;
for( char **t = numbers; t < e; t++ ){
printf(" length of %s is %d\n", *t, length(*t));
}
return 0;
}
#include <stdio.h>
int main(){
char arr[20]="Hello";
int count=0;
while(arr[count]!='[=10=]'){
count++;
}
printf("%d",count);
return 0;
}
看看这段小代码,你就明白了。在 C 中,字符串以 NULL 字符结尾。我们可以利用这个优势。
这个项目可以在不计算字符串长度的情况下完成。如何?在 C 中,所有字符串都是 nul-terminated 包含 nul-character '[=12=]'
(ASCII 值 0
)构成字符串的最后一个字符。当您需要遍历一个字符串时,您只需循环直到字符值为 0
(例如 nul-character)
这就是所有字符串函数知道何时停止读取字符的方式。由于您有一个包含字符串的 array-of-pointers ,因此您只需要遍历每个指针并为每个指针遍历每个字符,直到找到 nul 字符。
总而言之,(并指出您不需要 math.h
),您可以:
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
int nnumbers = sizeof numbers / sizeof *numbers; /* no. of elements */
for (int i = 0; i < nnumbers; i++) {
long long unsigned number = 0;
/* you don't care about the length, strings are nul-terminated,
* just loop until [=10=] is found.
*/
for (int j = 0; numbers[i][j]; j++) {
number <<= 1; /* shift left */
number += numbers[i][j] == '1' ? 1 : 0; /* add bit */
}
printf ("%s = %llu\n", numbers[i], number); /* output result */
}
return 0;
}
(注意: 您必须使用 64 位类型来保存转换后的值,因为 "1010110011010101111101111010101110110"
至少需要 38
位来表示)
例子Use/Output
将每个字符串转换为数值的简单示例输出:
$ ./bin/binstr2num
01001001 = 73
00101010 = 42
010100111001 = 1337
011111110100101010010111 = 8342167
0001010110011010101111101111010101110110 = 92790519158
01011100110000001101 = 379917
在 C 中,字符串实际上只是 char
数组,带有一个特殊的终止符来标记字符串的结尾。所以,假设你有这样的东西:
char *str = "hello";
这基本上等同于:
char str[] = {'h', 'e', 'l', 'l', 'o', '[=11=]'};
注意到数组末尾的 [=17=]
字符了吗?这是 C 放在字符串末尾的特殊终止符。像 strlen()
这样的函数几乎遍历 char
数组寻找第一次出现的 [=17=]
字符然后停止。
因此,您可以制作自己的 strlen()
版本,像这样说 my_strlen()
:
int my_strlen(char *str)
{
/* Initialize len to 0 */
int len = 0;
/* Iterate through str, increment len, and stop when we reach '[=12=]' */
while(str[len] != '[=12=]')
len++;
/* Return the len */
return len;
}
然后在你的 for
循环中,你可以调用这个函数。另外,请注意您对 numbers
数组大小的计算:
int length = sizeof(numbers);
不会给你数组中元素的数量。该代码为您提供大小(以字节为单位)或 numbers
,这是一个 char
指针数组。如果您想获得元素的数量,则必须将该大小除以单个元素(即 char
指针)的大小(以字节为单位)。所以,这样的事情会起作用:
int length = sizeof(numbers) / sizeof(numbers[0]);
您的最终代码可能如下所示:
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int my_strlen(char *str) {
/* Initialize len to 0 */
int len = 0;
/* Iterate through str, increment len, and stop when we reach '[=15=]' */
while(str[len] != '[=15=]')
len++;
/* Return the len */
return len;
}
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
// Add here..
// Notice the change here
int length = sizeof(numbers) / sizeof(numbers[0]);
for(int i = 0; i < length; i++ ){
int str_len = my_strlen(numbers[i]);
// Do what you need with str_len
}
return 0;
}