需要帮助来理解数组
Requiring help to understand arrays
我正在学习 C 中的数组,但我不明白为什么以下内容不正确?
#include <cs50.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
string plaintext = get_string();
int x = 5;
long long N = strlen(plaintext);
string a = plaintext;
long long c = 0;
int z = x;
for(int i = 0; i < N + (N/x) ; i++)
{
if( i == x)
{
a[c] = 32;
c++;
z = (z + x);
//printf("%c\n", a[c]);
}
a[c] = plaintext[i];
//printf("%c\n", a[c]);
c++;
}
printf("%s\n", a);
}
它的意思是在每 x 个字符之后将空格插入文本字符串中...我知道它效率不高(我想我需要一种叫做指针的东西)但为什么它不起作用?我使用调试器检查了它,我的原始字符串似乎在不断变化......但是为什么呢?
假设 string
是 char *
那么 text
和 a
指向同一个字符串。这解释了为什么您的原始字符串会发生变化。您可以做的是:
string a= malloc(N+1 + N/x +1);
这会为一个新字符串分配 space,您可以在每 x
个字符后使用 space 将原始字符串复制到其中。当 x
或 N
为奇数时,为空终止符加 1 和 1 "to be safe"。
#include <bits/stdc++.h>
using namespace std;
#define freinput "input.txt","r",stdin
#define freoutput "output.txt","w",stdout
#define mp make_pair
#define fi first
#define sc second
#define ellapse printf("Time : %0.3lf\n",clock()*1.0/CLOCKS_PER_SEC);
typedef long long ll;
typedef unsigned long int uld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
string s;
string stringInsertion(int x,string neww){
for(int i = 0;i<s.size();i++){
if(i!=0 && i%x==0){
neww=neww+' '+s[i];
}
else neww+=s[i];
}
return neww;
}
int main(){
cin>>s;
int x = 2;
string neww="";
cout<<stringInsertion(x,neww);
}
只需设置 x number.hope 这个帮助
好吧,让我们先做类似的事情:打印出带有spaces 的字符串。使用 i
遍历字符串。每次 i
被 x
整除时,我们在打印字符之前打印一个 space,但不是在开头:
void print_spaced(const char *s, int x)
{
int i;
for (i = 0; s[i]; i++) {
if (i && i % x == 0) putchar(' ');
putchar(s[i]);
}
putchar('\n');
}
你不需要事先确定长度,因为你可以在遇到终止空字符时停止。也就是说,只要 s[i]
不为空,就继续。 (回想一下,s[i]
与 s[i] != '[=20=]'
相同,类似地,i
与 i != 0
相同。)
现在让我们用 spaced 输出字符串填充一个 char 数组,而不是打印它:
int space_out_unsafe(char *res, const char *s, int x)
{
int i, k = 0;
for (i = 0; s[i]; i++) {
if (i && i % x == 0) res[k++] = ' ';
res[k++] = s[i];
}
res[k] = '[=11=]';
return k;
}
这个函数需要一个额外的参数:一个要填充的字符缓冲区。它有第二个索引,k
,这是结果缓冲区的当前长度。每当我们在第一个版本中打印时,我们现在都会在字符串中附加一个字符:
res[k++] = '#';
Tis 覆盖当前结尾并在一个位置上移动k
。我们不在最后写一个换行符,但我们必须以 null 终止结果。
但是有一个问题:缓冲区可能溢出;请注意我如何标记上面的函数 unsafe
。 C 中的数组具有固定大小,并且在追加某些内容时不会自动增长。因此,将最大缓冲区大小 max
传递给函数并在附加之前检查溢出是一个好主意:
int space_out(char *res, int max, const char *s, int x)
{
int i, k = 0;
for (i = 0; s[i]; i++) {
if (i && i % x == 0 && k < max - 1) res[k++] = ' ';
if (k < max - 1) res[k++] = s[i];
}
res[k] = '[=13=]';
return k;
}
您现在可以像这样使用此功能:
char res[20];
space_out(res, sizeof(res), "Doremifasola", 2);
puts(res);
还有其他方法可以做到这一点。您可以按照 Paul 的建议动态分配内存。这样,您可以满足您需要的额外 space,但您也让函数的调用者负责清理使用 free
分配的内存。动态分配内存是你第一周后要研究的事情。 :)
另一种可能是space原地取出字符串,即修改原始缓冲区的内容。不过,您仍然需要注意提供额外的 space。 (通常,当结果字符串较短时,例如过滤掉字符时,会使用就地中间化。)您还应该处理来自 和 的字符串,以免用 spaces 覆盖您稍后需要的数据。如果你有信心,这也是下周的练习。
我正在学习 C 中的数组,但我不明白为什么以下内容不正确?
#include <cs50.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
string plaintext = get_string();
int x = 5;
long long N = strlen(plaintext);
string a = plaintext;
long long c = 0;
int z = x;
for(int i = 0; i < N + (N/x) ; i++)
{
if( i == x)
{
a[c] = 32;
c++;
z = (z + x);
//printf("%c\n", a[c]);
}
a[c] = plaintext[i];
//printf("%c\n", a[c]);
c++;
}
printf("%s\n", a);
}
它的意思是在每 x 个字符之后将空格插入文本字符串中...我知道它效率不高(我想我需要一种叫做指针的东西)但为什么它不起作用?我使用调试器检查了它,我的原始字符串似乎在不断变化......但是为什么呢?
假设 string
是 char *
那么 text
和 a
指向同一个字符串。这解释了为什么您的原始字符串会发生变化。您可以做的是:
string a= malloc(N+1 + N/x +1);
这会为一个新字符串分配 space,您可以在每 x
个字符后使用 space 将原始字符串复制到其中。当 x
或 N
为奇数时,为空终止符加 1 和 1 "to be safe"。
#include <bits/stdc++.h>
using namespace std;
#define freinput "input.txt","r",stdin
#define freoutput "output.txt","w",stdout
#define mp make_pair
#define fi first
#define sc second
#define ellapse printf("Time : %0.3lf\n",clock()*1.0/CLOCKS_PER_SEC);
typedef long long ll;
typedef unsigned long int uld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
string s;
string stringInsertion(int x,string neww){
for(int i = 0;i<s.size();i++){
if(i!=0 && i%x==0){
neww=neww+' '+s[i];
}
else neww+=s[i];
}
return neww;
}
int main(){
cin>>s;
int x = 2;
string neww="";
cout<<stringInsertion(x,neww);
}
只需设置 x number.hope 这个帮助
好吧,让我们先做类似的事情:打印出带有spaces 的字符串。使用 i
遍历字符串。每次 i
被 x
整除时,我们在打印字符之前打印一个 space,但不是在开头:
void print_spaced(const char *s, int x)
{
int i;
for (i = 0; s[i]; i++) {
if (i && i % x == 0) putchar(' ');
putchar(s[i]);
}
putchar('\n');
}
你不需要事先确定长度,因为你可以在遇到终止空字符时停止。也就是说,只要 s[i]
不为空,就继续。 (回想一下,s[i]
与 s[i] != '[=20=]'
相同,类似地,i
与 i != 0
相同。)
现在让我们用 spaced 输出字符串填充一个 char 数组,而不是打印它:
int space_out_unsafe(char *res, const char *s, int x)
{
int i, k = 0;
for (i = 0; s[i]; i++) {
if (i && i % x == 0) res[k++] = ' ';
res[k++] = s[i];
}
res[k] = '[=11=]';
return k;
}
这个函数需要一个额外的参数:一个要填充的字符缓冲区。它有第二个索引,k
,这是结果缓冲区的当前长度。每当我们在第一个版本中打印时,我们现在都会在字符串中附加一个字符:
res[k++] = '#';
Tis 覆盖当前结尾并在一个位置上移动k
。我们不在最后写一个换行符,但我们必须以 null 终止结果。
但是有一个问题:缓冲区可能溢出;请注意我如何标记上面的函数 unsafe
。 C 中的数组具有固定大小,并且在追加某些内容时不会自动增长。因此,将最大缓冲区大小 max
传递给函数并在附加之前检查溢出是一个好主意:
int space_out(char *res, int max, const char *s, int x)
{
int i, k = 0;
for (i = 0; s[i]; i++) {
if (i && i % x == 0 && k < max - 1) res[k++] = ' ';
if (k < max - 1) res[k++] = s[i];
}
res[k] = '[=13=]';
return k;
}
您现在可以像这样使用此功能:
char res[20];
space_out(res, sizeof(res), "Doremifasola", 2);
puts(res);
还有其他方法可以做到这一点。您可以按照 Paul 的建议动态分配内存。这样,您可以满足您需要的额外 space,但您也让函数的调用者负责清理使用 free
分配的内存。动态分配内存是你第一周后要研究的事情。 :)
另一种可能是space原地取出字符串,即修改原始缓冲区的内容。不过,您仍然需要注意提供额外的 space。 (通常,当结果字符串较短时,例如过滤掉字符时,会使用就地中间化。)您还应该处理来自 和 的字符串,以免用 spaces 覆盖您稍后需要的数据。如果你有信心,这也是下周的练习。