jni 字符串的梳理 2 字符串的处理操作

我们实现下面的一个功能:

1、首先在java层传递一个字符串到c层,c层首先将jstring转换成char*类型,然后将两个字符串相加,然后再再将char*类型转换成jstring,在上层显示出来

我们来看底层程序的代码:

//
// Created by wei.yuan on 2017/6/13.
//
#include <jni.h>
#include <string.h>
#include <pthread.h>
#include "im_weiyuan_com_jni_Sdk.h"
#include "im_weiyuan_com_jni_Sdk_OnSubProgressListener.h"
#include "im_weiyuan_com_jni_Sdk_SdkHodler.h"
JavaVM *g_VM;
jobject g_obj;
#include <jni.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <assert.h>
#include <android\log.h>
#include <errno.h>
#include <pthread.h>
#include <android/log.h>

#define LOG_TAG "Native"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

/*方法三,调用C库函数,*/
char* join(char *s1, char *s2)
{
    char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator
    //in real code you would check for errors in malloc here
    if (result == NULL) exit (1);

    strcpy(result, s1);
    strcat(result, s2);

    return result;
}

/*1、第一步将输入的jstring类型转换成char*类型
 * 2、将两个char*类型的字符串拼接起来
 * 3、将cha*类型的转换成jstring类型,返回给java层
 *
 *
 *
 *
 */
JNIEXPORT jstring JNICALL Java_im_weiyuan_com_jni_Sdk_getStringFromC
        (JNIEnv * env, jobject jobj, jstring jstr){
    const jbyte *str;

    str = (*env)->GetStringUTFChars(env, jstr, NULL);

    if (str == NULL) {

        return NULL; /* OutOfMemoryError already thrown */

    }
    LOGE("123456789:%s\n",str);
    char *hello = "I from C++";

    char*result = NULL;
    result = join(str,hello);

    LOGE("123456789 result len is :%d\n",strlen(result));
    (*env)->ReleaseStringUTFChars(env, jstr, str);
    //malloc申请的内存记得要是否
    if(result !=NULL){
        LOGE("123456789 result len is free\n");
        free(result);
    }
    return (*env)->NewStringUTF(env, result);
}

这里一定要注意strcat和strcpy的使用方式:

上面的代码还有一个致命的问题:

要为所需的内存分配足够的空间,否则会出现严重的错误。同时,分配的时候若想使用strlen()来确定内存大小时,要注意进行转换,因为内存中是以字节数来计算大小的,而strlen返回的只是字符串长度,如strlen("abc")返回的3,但是可能每个字符占两字节(不同系统有所不同),即内存大小应该为6。

所以上面的代码应该写成下面的形式:

/*方法三,调用C库函数,*/
char* join(char *s1, char *s2)
{
    char *result = malloc((strlen(s1)+strlen(s2)+1)* sizeof(char));//+1 for the zero-terminator
    //in real code you would check for errors in malloc here
    if (result == NULL) exit (1);

    strcpy(result, s1);
    strcat(result, s2);

    return result;
}
头文件:#include <string.h>

strcat() 函数用来连接字符串,其原型为:
    char *strcat(char *dest, const char *src);

【参数】dest 为目的字符串指针,src 为源字符串指针。

strcat() 会将参数 src 字符串复制到参数 dest 所指的字符串尾部;dest 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL。

注意:dest 与 src 所指的内存空间不能重叠,且 dest 要有足够的空间来容纳要复制的字符串。

【返回值】返回dest 字符串起始地址。

【实例】连接字符串并输出。
#include <stdio.h>
#include <string.h>

int main ()
{
    char str[80];
    strcpy (str,"these ");
    strcat (str,"strings ");
    strcat (str,"are ");
    strcat (str,"concatenated.");
    puts (str);
    return 0;
}

错误案例一:

在实际开放中,我们可能会用到strcat拼接两个字符串,例如

char a[6] = "hello";
char b[6] = "world";
strcat(a,b);
free(a);
free(b);

此时会出现越界情况,由于a只有6个字符的空间,拼接后超出了本身空间大小,因此会报错,
所以需要用realloc重新给a分配足够的空间来存储新的字符串。

在使用指针时,需要时刻注意空间的分配,空间的大小,空间的释放等问题
时间: 2024-10-29 12:36:44

jni 字符串的梳理 2 字符串的处理操作的相关文章

JNI的某些数组和字符串类型转换

JNICC++C#Windows jbytearray转c++byte数组 C代码   [c] view plaincopy jbyte * arrayBody = env->GetByteArrayElements(data,0); jsize theArrayLengthJ = env->GetArrayLength(data); BYTE * starter = (BYTE *)arrayBody;jbyteArray 转 c++中的BYTE[] C代码   [c] view plain

string字符串转C风格字符串 进而转换为数字

要求如题 头文件stdlib.h中有一个函数atof() 可以将字符串转化为双精度浮点数(double) double atof(const char *nptr); 此字符串为C风格字符串,因此需要将string转化为C风格字符串 此时可用到一个函数c_str() const char *c_str() 参考资料: string中c_str().data().copy(p,n)函数的用法 在使用c_str()时遇到了一个问题–此函数的返回值为const char * 因为是const数据类型,

【C语言】将一个数字字符串转换成这个字符串对应的数字(包括正浮点数、负浮点数)

#include <stdio.h> /* 编写一个函数,将一个数字字符串转换成这个字符串对应的数字(包括正浮点数.负浮点数) 例如:"12.34" 返回12.34 "-123.34" 返回-123.34 函数原型:double my_atof(char *str) {} */ double my_atof(char *str) { double m=0,n=0,x=1; int flag=1; int flag2=0; if(*str=='-') //

【C语言】编写一个函数,将一个数字字符串转换成该字符串对应的数字(包括正整数、负整数)

/* 编写一个函数,将一个数字字符串转换成该字符串对应的数字(包括正整数.负整数) 例如:"12" 返回12 "-123" 返回-123 函数原型:int my_atof(char *str) */ #include <stdio.h> int my_atof(char *str) { int flag=0; int m=0; if(*str=='-') { flag=1; str++; } while(*str!='\0') { if(*str<

Java实现统计某字符串在另一个字符串中出现的次数

面试时会经常考这样的题目,估计也不让使用正则表达式.还好这个算法还算简单,不过在草稿纸上写难免会出现运行异常,好吧,面试官赢了,乃们屌丝就实实在在的把代码码出来吧. 下面是实现代码: /** * 统计某字符串在另一个字符串中出现的次数 * * */ public class CountHit { public static void main(String[] args) { String a = "123456abcde6ab"; String b = "6abc"

【编程题目】有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配...

37.(字符串)有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配,则两个字符串可以联接,问这 n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误. 分析:如果出现循环,则返回错误 这句不懂 具体做法是先给每个字符串建一个vector 存入每个字符串后面可以匹配的字符串序号 然后遍历所有的搭配情况,找到最长的. 我的遍历代码很丑... 可谓又臭又长..... 深深的自我鄙视. /* 37.(字符串) 有 n 个长为 m+1 的字符串

C++中对字符串进行插入、替换、删除操作

#include <iostream> #include <string> using std::cout; using std::endl; using std::string; int main(void){ string str1="We can insert a string"; string str2="a str into "; //在字符串指定位置前面插入指定字符串 cout <<str1.insert(14,str

Python_03_字符串_数据类型_for循环_列表操作

个人笔记,仅作学习记录,如有错误烦请指正 字符串: str1 = "这是一个字符串" str2 = '这也是一个字符串' 一般字符串都需要用双引号或单引号引起来 在Python中双引号和单引号是一样的,但必须成对出现 msg = "i'm liming" # 此处因为字符串中包含单引号,所以外边用双引号引起来表示字符串内容 msg = """收到消息"i'm liming".""" #

输入一个字符串,输出该字符串中对称的子字符串的最大长度。

public class LongestSymmtricalLength2 { /* * Q75题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度. * 比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4. */ public static void main(String[] args) { String[] strs = { "a","google", "elgoog", "agol